1*9787f5e2SThor Thayer /* 2*9787f5e2SThor Thayer * Copyright Intel Corporation (C) 2014-2016. All Rights Reserved 3*9787f5e2SThor Thayer * 4*9787f5e2SThor Thayer * This program is free software; you can redistribute it and/or modify it 5*9787f5e2SThor Thayer * under the terms and conditions of the GNU General Public License, 6*9787f5e2SThor Thayer * version 2, as published by the Free Software Foundation. 7*9787f5e2SThor Thayer * 8*9787f5e2SThor Thayer * This program is distributed in the hope it will be useful, but WITHOUT 9*9787f5e2SThor Thayer * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10*9787f5e2SThor Thayer * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for 11*9787f5e2SThor Thayer * more details. 12*9787f5e2SThor Thayer * 13*9787f5e2SThor Thayer * You should have received a copy of the GNU General Public License along with 14*9787f5e2SThor Thayer * this program. If not, see <http://www.gnu.org/licenses/>. 15*9787f5e2SThor Thayer * 16*9787f5e2SThor Thayer * SPI access for Altera Arria10 MAX5 System Resource Chip 17*9787f5e2SThor Thayer * 18*9787f5e2SThor Thayer * Adapted from DA9052 19*9787f5e2SThor Thayer */ 20*9787f5e2SThor Thayer 21*9787f5e2SThor Thayer #include <linux/mfd/altera-a10sr.h> 22*9787f5e2SThor Thayer #include <linux/mfd/core.h> 23*9787f5e2SThor Thayer #include <linux/module.h> 24*9787f5e2SThor Thayer #include <linux/of.h> 25*9787f5e2SThor Thayer #include <linux/spi/spi.h> 26*9787f5e2SThor Thayer 27*9787f5e2SThor Thayer static const struct mfd_cell altr_a10sr_subdev_info[] = { 28*9787f5e2SThor Thayer { 29*9787f5e2SThor Thayer .name = "altr_a10sr_gpio", 30*9787f5e2SThor Thayer .of_compatible = "altr,a10sr-gpio", 31*9787f5e2SThor Thayer }, 32*9787f5e2SThor Thayer }; 33*9787f5e2SThor Thayer 34*9787f5e2SThor Thayer static bool altr_a10sr_reg_readable(struct device *dev, unsigned int reg) 35*9787f5e2SThor Thayer { 36*9787f5e2SThor Thayer switch (reg) { 37*9787f5e2SThor Thayer case ALTR_A10SR_VERSION_READ: 38*9787f5e2SThor Thayer case ALTR_A10SR_LED_REG: 39*9787f5e2SThor Thayer case ALTR_A10SR_PBDSW_REG: 40*9787f5e2SThor Thayer case ALTR_A10SR_PBDSW_IRQ_REG: 41*9787f5e2SThor Thayer case ALTR_A10SR_PWR_GOOD1_REG: 42*9787f5e2SThor Thayer case ALTR_A10SR_PWR_GOOD2_REG: 43*9787f5e2SThor Thayer case ALTR_A10SR_PWR_GOOD3_REG: 44*9787f5e2SThor Thayer case ALTR_A10SR_FMCAB_REG: 45*9787f5e2SThor Thayer case ALTR_A10SR_HPS_RST_REG: 46*9787f5e2SThor Thayer case ALTR_A10SR_USB_QSPI_REG: 47*9787f5e2SThor Thayer case ALTR_A10SR_SFPA_REG: 48*9787f5e2SThor Thayer case ALTR_A10SR_SFPB_REG: 49*9787f5e2SThor Thayer case ALTR_A10SR_I2C_M_REG: 50*9787f5e2SThor Thayer case ALTR_A10SR_WARM_RST_REG: 51*9787f5e2SThor Thayer case ALTR_A10SR_WR_KEY_REG: 52*9787f5e2SThor Thayer case ALTR_A10SR_PMBUS_REG: 53*9787f5e2SThor Thayer return true; 54*9787f5e2SThor Thayer default: 55*9787f5e2SThor Thayer return false; 56*9787f5e2SThor Thayer } 57*9787f5e2SThor Thayer } 58*9787f5e2SThor Thayer 59*9787f5e2SThor Thayer static bool altr_a10sr_reg_writeable(struct device *dev, unsigned int reg) 60*9787f5e2SThor Thayer { 61*9787f5e2SThor Thayer switch (reg) { 62*9787f5e2SThor Thayer case ALTR_A10SR_LED_REG: 63*9787f5e2SThor Thayer case ALTR_A10SR_PBDSW_IRQ_REG: 64*9787f5e2SThor Thayer case ALTR_A10SR_FMCAB_REG: 65*9787f5e2SThor Thayer case ALTR_A10SR_HPS_RST_REG: 66*9787f5e2SThor Thayer case ALTR_A10SR_USB_QSPI_REG: 67*9787f5e2SThor Thayer case ALTR_A10SR_SFPA_REG: 68*9787f5e2SThor Thayer case ALTR_A10SR_SFPB_REG: 69*9787f5e2SThor Thayer case ALTR_A10SR_WARM_RST_REG: 70*9787f5e2SThor Thayer case ALTR_A10SR_WR_KEY_REG: 71*9787f5e2SThor Thayer case ALTR_A10SR_PMBUS_REG: 72*9787f5e2SThor Thayer return true; 73*9787f5e2SThor Thayer default: 74*9787f5e2SThor Thayer return false; 75*9787f5e2SThor Thayer } 76*9787f5e2SThor Thayer } 77*9787f5e2SThor Thayer 78*9787f5e2SThor Thayer static bool altr_a10sr_reg_volatile(struct device *dev, unsigned int reg) 79*9787f5e2SThor Thayer { 80*9787f5e2SThor Thayer switch (reg) { 81*9787f5e2SThor Thayer case ALTR_A10SR_PBDSW_REG: 82*9787f5e2SThor Thayer case ALTR_A10SR_PBDSW_IRQ_REG: 83*9787f5e2SThor Thayer case ALTR_A10SR_PWR_GOOD1_REG: 84*9787f5e2SThor Thayer case ALTR_A10SR_PWR_GOOD2_REG: 85*9787f5e2SThor Thayer case ALTR_A10SR_PWR_GOOD3_REG: 86*9787f5e2SThor Thayer case ALTR_A10SR_HPS_RST_REG: 87*9787f5e2SThor Thayer case ALTR_A10SR_I2C_M_REG: 88*9787f5e2SThor Thayer case ALTR_A10SR_WARM_RST_REG: 89*9787f5e2SThor Thayer case ALTR_A10SR_WR_KEY_REG: 90*9787f5e2SThor Thayer case ALTR_A10SR_PMBUS_REG: 91*9787f5e2SThor Thayer return true; 92*9787f5e2SThor Thayer default: 93*9787f5e2SThor Thayer return false; 94*9787f5e2SThor Thayer } 95*9787f5e2SThor Thayer } 96*9787f5e2SThor Thayer 97*9787f5e2SThor Thayer const struct regmap_config altr_a10sr_regmap_config = { 98*9787f5e2SThor Thayer .reg_bits = 8, 99*9787f5e2SThor Thayer .val_bits = 8, 100*9787f5e2SThor Thayer 101*9787f5e2SThor Thayer .cache_type = REGCACHE_NONE, 102*9787f5e2SThor Thayer 103*9787f5e2SThor Thayer .use_single_rw = true, 104*9787f5e2SThor Thayer .read_flag_mask = 1, 105*9787f5e2SThor Thayer .write_flag_mask = 0, 106*9787f5e2SThor Thayer 107*9787f5e2SThor Thayer .max_register = ALTR_A10SR_WR_KEY_REG, 108*9787f5e2SThor Thayer .readable_reg = altr_a10sr_reg_readable, 109*9787f5e2SThor Thayer .writeable_reg = altr_a10sr_reg_writeable, 110*9787f5e2SThor Thayer .volatile_reg = altr_a10sr_reg_volatile, 111*9787f5e2SThor Thayer 112*9787f5e2SThor Thayer }; 113*9787f5e2SThor Thayer 114*9787f5e2SThor Thayer static int altr_a10sr_spi_probe(struct spi_device *spi) 115*9787f5e2SThor Thayer { 116*9787f5e2SThor Thayer int ret; 117*9787f5e2SThor Thayer struct altr_a10sr *a10sr; 118*9787f5e2SThor Thayer 119*9787f5e2SThor Thayer a10sr = devm_kzalloc(&spi->dev, sizeof(*a10sr), 120*9787f5e2SThor Thayer GFP_KERNEL); 121*9787f5e2SThor Thayer if (!a10sr) 122*9787f5e2SThor Thayer return -ENOMEM; 123*9787f5e2SThor Thayer 124*9787f5e2SThor Thayer spi->mode = SPI_MODE_3; 125*9787f5e2SThor Thayer spi->bits_per_word = 8; 126*9787f5e2SThor Thayer spi_setup(spi); 127*9787f5e2SThor Thayer 128*9787f5e2SThor Thayer a10sr->dev = &spi->dev; 129*9787f5e2SThor Thayer 130*9787f5e2SThor Thayer spi_set_drvdata(spi, a10sr); 131*9787f5e2SThor Thayer 132*9787f5e2SThor Thayer a10sr->regmap = devm_regmap_init_spi(spi, &altr_a10sr_regmap_config); 133*9787f5e2SThor Thayer if (IS_ERR(a10sr->regmap)) { 134*9787f5e2SThor Thayer ret = PTR_ERR(a10sr->regmap); 135*9787f5e2SThor Thayer dev_err(&spi->dev, "Failed to allocate register map: %d\n", 136*9787f5e2SThor Thayer ret); 137*9787f5e2SThor Thayer return ret; 138*9787f5e2SThor Thayer } 139*9787f5e2SThor Thayer 140*9787f5e2SThor Thayer ret = devm_mfd_add_devices(a10sr->dev, PLATFORM_DEVID_AUTO, 141*9787f5e2SThor Thayer altr_a10sr_subdev_info, 142*9787f5e2SThor Thayer ARRAY_SIZE(altr_a10sr_subdev_info), 143*9787f5e2SThor Thayer NULL, 0, NULL); 144*9787f5e2SThor Thayer if (ret) 145*9787f5e2SThor Thayer dev_err(a10sr->dev, "Failed to register sub-devices: %d\n", 146*9787f5e2SThor Thayer ret); 147*9787f5e2SThor Thayer 148*9787f5e2SThor Thayer return ret; 149*9787f5e2SThor Thayer } 150*9787f5e2SThor Thayer 151*9787f5e2SThor Thayer static const struct of_device_id altr_a10sr_spi_of_match[] = { 152*9787f5e2SThor Thayer { .compatible = "altr,a10sr" }, 153*9787f5e2SThor Thayer { }, 154*9787f5e2SThor Thayer }; 155*9787f5e2SThor Thayer MODULE_DEVICE_TABLE(of, altr_a10sr_spi_of_match); 156*9787f5e2SThor Thayer 157*9787f5e2SThor Thayer static struct spi_driver altr_a10sr_spi_driver = { 158*9787f5e2SThor Thayer .probe = altr_a10sr_spi_probe, 159*9787f5e2SThor Thayer .driver = { 160*9787f5e2SThor Thayer .name = "altr_a10sr", 161*9787f5e2SThor Thayer .of_match_table = of_match_ptr(altr_a10sr_spi_of_match), 162*9787f5e2SThor Thayer }, 163*9787f5e2SThor Thayer }; 164*9787f5e2SThor Thayer 165*9787f5e2SThor Thayer module_spi_driver(altr_a10sr_spi_driver); 166*9787f5e2SThor Thayer 167*9787f5e2SThor Thayer MODULE_LICENSE("GPL v2"); 168*9787f5e2SThor Thayer MODULE_AUTHOR("Thor Thayer <tthayer@opensource.altera.com>"); 169*9787f5e2SThor Thayer MODULE_DESCRIPTION("Altera Arria10 DevKit System Resource MFD Driver"); 170