9952f6918d
Based on 1 normalized pattern(s): this program is free software you can redistribute it and or modify it under the terms and conditions of the gnu general public license version 2 as published by the free software foundation this program is distributed in the hope it will be useful but without any warranty without even the implied warranty of merchantability or fitness for a particular purpose see the gnu general public license for more details you should have received a copy of the gnu general public license along with this program if not see http www gnu org licenses extracted by the scancode license scanner the SPDX license identifier GPL-2.0-only has been chosen to replace the boilerplate/reference in 228 file(s). Signed-off-by: Thomas Gleixner <tglx@linutronix.de> Reviewed-by: Allison Randal <allison@lohutok.net> Reviewed-by: Steve Winslow <swinslow@gmail.com> Reviewed-by: Richard Fontana <rfontana@redhat.com> Reviewed-by: Alexios Zavras <alexios.zavras@intel.com> Cc: linux-spdx@vger.kernel.org Link: https://lkml.kernel.org/r/20190528171438.107155473@linutronix.de Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
162 lines
3.6 KiB
C
162 lines
3.6 KiB
C
// SPDX-License-Identifier: GPL-2.0-only
|
|
/*
|
|
* Altera Arria10 DevKit System Resource MFD Driver
|
|
*
|
|
* Author: Thor Thayer <tthayer@opensource.altera.com>
|
|
*
|
|
* Copyright Intel Corporation (C) 2014-2016. All Rights Reserved
|
|
*
|
|
* SPI access for Altera Arria10 MAX5 System Resource Chip
|
|
*
|
|
* Adapted from DA9052
|
|
*/
|
|
|
|
#include <linux/mfd/altera-a10sr.h>
|
|
#include <linux/mfd/core.h>
|
|
#include <linux/init.h>
|
|
#include <linux/of.h>
|
|
#include <linux/spi/spi.h>
|
|
|
|
static const struct mfd_cell altr_a10sr_subdev_info[] = {
|
|
{
|
|
.name = "altr_a10sr_gpio",
|
|
.of_compatible = "altr,a10sr-gpio",
|
|
},
|
|
{
|
|
.name = "altr_a10sr_reset",
|
|
.of_compatible = "altr,a10sr-reset",
|
|
},
|
|
};
|
|
|
|
static bool altr_a10sr_reg_readable(struct device *dev, unsigned int reg)
|
|
{
|
|
switch (reg) {
|
|
case ALTR_A10SR_VERSION_READ:
|
|
case ALTR_A10SR_LED_REG:
|
|
case ALTR_A10SR_PBDSW_REG:
|
|
case ALTR_A10SR_PBDSW_IRQ_REG:
|
|
case ALTR_A10SR_PWR_GOOD1_REG:
|
|
case ALTR_A10SR_PWR_GOOD2_REG:
|
|
case ALTR_A10SR_PWR_GOOD3_REG:
|
|
case ALTR_A10SR_FMCAB_REG:
|
|
case ALTR_A10SR_HPS_RST_REG:
|
|
case ALTR_A10SR_USB_QSPI_REG:
|
|
case ALTR_A10SR_SFPA_REG:
|
|
case ALTR_A10SR_SFPB_REG:
|
|
case ALTR_A10SR_I2C_M_REG:
|
|
case ALTR_A10SR_WARM_RST_REG:
|
|
case ALTR_A10SR_WR_KEY_REG:
|
|
case ALTR_A10SR_PMBUS_REG:
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
static bool altr_a10sr_reg_writeable(struct device *dev, unsigned int reg)
|
|
{
|
|
switch (reg) {
|
|
case ALTR_A10SR_LED_REG:
|
|
case ALTR_A10SR_PBDSW_IRQ_REG:
|
|
case ALTR_A10SR_FMCAB_REG:
|
|
case ALTR_A10SR_HPS_RST_REG:
|
|
case ALTR_A10SR_USB_QSPI_REG:
|
|
case ALTR_A10SR_SFPA_REG:
|
|
case ALTR_A10SR_SFPB_REG:
|
|
case ALTR_A10SR_WARM_RST_REG:
|
|
case ALTR_A10SR_WR_KEY_REG:
|
|
case ALTR_A10SR_PMBUS_REG:
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
static bool altr_a10sr_reg_volatile(struct device *dev, unsigned int reg)
|
|
{
|
|
switch (reg) {
|
|
case ALTR_A10SR_PBDSW_REG:
|
|
case ALTR_A10SR_PBDSW_IRQ_REG:
|
|
case ALTR_A10SR_PWR_GOOD1_REG:
|
|
case ALTR_A10SR_PWR_GOOD2_REG:
|
|
case ALTR_A10SR_PWR_GOOD3_REG:
|
|
case ALTR_A10SR_HPS_RST_REG:
|
|
case ALTR_A10SR_I2C_M_REG:
|
|
case ALTR_A10SR_WARM_RST_REG:
|
|
case ALTR_A10SR_WR_KEY_REG:
|
|
case ALTR_A10SR_PMBUS_REG:
|
|
return true;
|
|
default:
|
|
return false;
|
|
}
|
|
}
|
|
|
|
static const struct regmap_config altr_a10sr_regmap_config = {
|
|
.reg_bits = 8,
|
|
.val_bits = 8,
|
|
|
|
.cache_type = REGCACHE_NONE,
|
|
|
|
.use_single_read = true,
|
|
.use_single_write = true,
|
|
.read_flag_mask = 1,
|
|
.write_flag_mask = 0,
|
|
|
|
.max_register = ALTR_A10SR_WR_KEY_REG,
|
|
.readable_reg = altr_a10sr_reg_readable,
|
|
.writeable_reg = altr_a10sr_reg_writeable,
|
|
.volatile_reg = altr_a10sr_reg_volatile,
|
|
|
|
};
|
|
|
|
static int altr_a10sr_spi_probe(struct spi_device *spi)
|
|
{
|
|
int ret;
|
|
struct altr_a10sr *a10sr;
|
|
|
|
a10sr = devm_kzalloc(&spi->dev, sizeof(*a10sr),
|
|
GFP_KERNEL);
|
|
if (!a10sr)
|
|
return -ENOMEM;
|
|
|
|
spi->mode = SPI_MODE_3;
|
|
spi->bits_per_word = 8;
|
|
spi_setup(spi);
|
|
|
|
a10sr->dev = &spi->dev;
|
|
|
|
spi_set_drvdata(spi, a10sr);
|
|
|
|
a10sr->regmap = devm_regmap_init_spi(spi, &altr_a10sr_regmap_config);
|
|
if (IS_ERR(a10sr->regmap)) {
|
|
ret = PTR_ERR(a10sr->regmap);
|
|
dev_err(&spi->dev, "Failed to allocate register map: %d\n",
|
|
ret);
|
|
return ret;
|
|
}
|
|
|
|
ret = devm_mfd_add_devices(a10sr->dev, PLATFORM_DEVID_AUTO,
|
|
altr_a10sr_subdev_info,
|
|
ARRAY_SIZE(altr_a10sr_subdev_info),
|
|
NULL, 0, NULL);
|
|
if (ret)
|
|
dev_err(a10sr->dev, "Failed to register sub-devices: %d\n",
|
|
ret);
|
|
|
|
return ret;
|
|
}
|
|
|
|
static const struct of_device_id altr_a10sr_spi_of_match[] = {
|
|
{ .compatible = "altr,a10sr" },
|
|
{ },
|
|
};
|
|
|
|
static struct spi_driver altr_a10sr_spi_driver = {
|
|
.probe = altr_a10sr_spi_probe,
|
|
.driver = {
|
|
.name = "altr_a10sr",
|
|
.of_match_table = of_match_ptr(altr_a10sr_spi_of_match),
|
|
},
|
|
};
|
|
builtin_driver(altr_a10sr_spi_driver, spi_register_driver)
|