171 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Altera Arria10 DevKit System Resource MFD Driver4 *5 * Author: Thor Thayer <tthayer@opensource.altera.com>6 *7 * Copyright Intel Corporation (C) 2014-2016. All Rights Reserved8 *9 * SPI access for Altera Arria10 MAX5 System Resource Chip10 *11 * Adapted from DA905212 */13 14#include <linux/mfd/altera-a10sr.h>15#include <linux/mfd/core.h>16#include <linux/init.h>17#include <linux/module.h>18#include <linux/of.h>19#include <linux/spi/spi.h>20 21static const struct mfd_cell altr_a10sr_subdev_info[] = {22 {23 .name = "altr_a10sr_gpio",24 .of_compatible = "altr,a10sr-gpio",25 },26 {27 .name = "altr_a10sr_reset",28 .of_compatible = "altr,a10sr-reset",29 },30};31 32static bool altr_a10sr_reg_readable(struct device *dev, unsigned int reg)33{34 switch (reg) {35 case ALTR_A10SR_VERSION_READ:36 case ALTR_A10SR_LED_REG:37 case ALTR_A10SR_PBDSW_REG:38 case ALTR_A10SR_PBDSW_IRQ_REG:39 case ALTR_A10SR_PWR_GOOD1_REG:40 case ALTR_A10SR_PWR_GOOD2_REG:41 case ALTR_A10SR_PWR_GOOD3_REG:42 case ALTR_A10SR_FMCAB_REG:43 case ALTR_A10SR_HPS_RST_REG:44 case ALTR_A10SR_USB_QSPI_REG:45 case ALTR_A10SR_SFPA_REG:46 case ALTR_A10SR_SFPB_REG:47 case ALTR_A10SR_I2C_M_REG:48 case ALTR_A10SR_WARM_RST_REG:49 case ALTR_A10SR_WR_KEY_REG:50 case ALTR_A10SR_PMBUS_REG:51 return true;52 default:53 return false;54 }55}56 57static bool altr_a10sr_reg_writeable(struct device *dev, unsigned int reg)58{59 switch (reg) {60 case ALTR_A10SR_LED_REG:61 case ALTR_A10SR_PBDSW_IRQ_REG:62 case ALTR_A10SR_FMCAB_REG:63 case ALTR_A10SR_HPS_RST_REG:64 case ALTR_A10SR_USB_QSPI_REG:65 case ALTR_A10SR_SFPA_REG:66 case ALTR_A10SR_SFPB_REG:67 case ALTR_A10SR_WARM_RST_REG:68 case ALTR_A10SR_WR_KEY_REG:69 case ALTR_A10SR_PMBUS_REG:70 return true;71 default:72 return false;73 }74}75 76static bool altr_a10sr_reg_volatile(struct device *dev, unsigned int reg)77{78 switch (reg) {79 case ALTR_A10SR_PBDSW_REG:80 case ALTR_A10SR_PBDSW_IRQ_REG:81 case ALTR_A10SR_PWR_GOOD1_REG:82 case ALTR_A10SR_PWR_GOOD2_REG:83 case ALTR_A10SR_PWR_GOOD3_REG:84 case ALTR_A10SR_HPS_RST_REG:85 case ALTR_A10SR_I2C_M_REG:86 case ALTR_A10SR_WARM_RST_REG:87 case ALTR_A10SR_WR_KEY_REG:88 case ALTR_A10SR_PMBUS_REG:89 return true;90 default:91 return false;92 }93}94 95static const struct regmap_config altr_a10sr_regmap_config = {96 .reg_bits = 8,97 .val_bits = 8,98 99 .cache_type = REGCACHE_NONE,100 101 .use_single_read = true,102 .use_single_write = true,103 .read_flag_mask = 1,104 .write_flag_mask = 0,105 106 .max_register = ALTR_A10SR_WR_KEY_REG,107 .readable_reg = altr_a10sr_reg_readable,108 .writeable_reg = altr_a10sr_reg_writeable,109 .volatile_reg = altr_a10sr_reg_volatile,110 111};112 113static int altr_a10sr_spi_probe(struct spi_device *spi)114{115 int ret;116 struct altr_a10sr *a10sr;117 118 a10sr = devm_kzalloc(&spi->dev, sizeof(*a10sr),119 GFP_KERNEL);120 if (!a10sr)121 return -ENOMEM;122 123 spi->mode = SPI_MODE_3;124 spi->bits_per_word = 8;125 spi_setup(spi);126 127 a10sr->dev = &spi->dev;128 129 spi_set_drvdata(spi, a10sr);130 131 a10sr->regmap = devm_regmap_init_spi(spi, &altr_a10sr_regmap_config);132 if (IS_ERR(a10sr->regmap)) {133 ret = PTR_ERR(a10sr->regmap);134 dev_err(&spi->dev, "Failed to allocate register map: %d\n",135 ret);136 return ret;137 }138 139 ret = devm_mfd_add_devices(a10sr->dev, PLATFORM_DEVID_AUTO,140 altr_a10sr_subdev_info,141 ARRAY_SIZE(altr_a10sr_subdev_info),142 NULL, 0, NULL);143 if (ret)144 dev_err(a10sr->dev, "Failed to register sub-devices: %d\n",145 ret);146 147 return ret;148}149 150static const struct of_device_id altr_a10sr_spi_of_match[] = {151 { .compatible = "altr,a10sr" },152 { },153};154MODULE_DEVICE_TABLE(of, altr_a10sr_spi_of_match);155 156static const struct spi_device_id altr_a10sr_spi_ids[] = {157 { .name = "a10sr" },158 { },159};160MODULE_DEVICE_TABLE(spi, altr_a10sr_spi_ids);161 162static struct spi_driver altr_a10sr_spi_driver = {163 .probe = altr_a10sr_spi_probe,164 .driver = {165 .name = "altr_a10sr",166 .of_match_table = altr_a10sr_spi_of_match,167 },168 .id_table = altr_a10sr_spi_ids,169};170builtin_driver(altr_a10sr_spi_driver, spi_register_driver)171