xref: /openbmc/linux/drivers/mfd/altera-a10sr.c (revision 23fa9421)
19952f691SThomas Gleixner // SPDX-License-Identifier: GPL-2.0-only
29787f5e2SThor Thayer /*
30a589167SPaul Gortmaker  * Altera Arria10 DevKit System Resource MFD Driver
40a589167SPaul Gortmaker  *
50a589167SPaul Gortmaker  * Author: Thor Thayer <tthayer@opensource.altera.com>
60a589167SPaul Gortmaker  *
79787f5e2SThor Thayer  * Copyright Intel Corporation (C) 2014-2016. All Rights Reserved
89787f5e2SThor Thayer  *
99787f5e2SThor Thayer  * SPI access for Altera Arria10 MAX5 System Resource Chip
109787f5e2SThor Thayer  *
119787f5e2SThor Thayer  * Adapted from DA9052
129787f5e2SThor Thayer  */
139787f5e2SThor Thayer 
149787f5e2SThor Thayer #include <linux/mfd/altera-a10sr.h>
159787f5e2SThor Thayer #include <linux/mfd/core.h>
160a589167SPaul Gortmaker #include <linux/init.h>
1737f127cfSArnd Bergmann #include <linux/module.h>
189787f5e2SThor Thayer #include <linux/of.h>
199787f5e2SThor Thayer #include <linux/spi/spi.h>
209787f5e2SThor Thayer 
219787f5e2SThor Thayer static const struct mfd_cell altr_a10sr_subdev_info[] = {
229787f5e2SThor Thayer 	{
239787f5e2SThor Thayer 		.name = "altr_a10sr_gpio",
249787f5e2SThor Thayer 		.of_compatible = "altr,a10sr-gpio",
259787f5e2SThor Thayer 	},
26dd47e972SThor Thayer 	{
27dd47e972SThor Thayer 		.name = "altr_a10sr_reset",
28dd47e972SThor Thayer 		.of_compatible = "altr,a10sr-reset",
29dd47e972SThor Thayer 	},
309787f5e2SThor Thayer };
319787f5e2SThor Thayer 
altr_a10sr_reg_readable(struct device * dev,unsigned int reg)329787f5e2SThor Thayer static bool altr_a10sr_reg_readable(struct device *dev, unsigned int reg)
339787f5e2SThor Thayer {
349787f5e2SThor Thayer 	switch (reg) {
359787f5e2SThor Thayer 	case ALTR_A10SR_VERSION_READ:
369787f5e2SThor Thayer 	case ALTR_A10SR_LED_REG:
379787f5e2SThor Thayer 	case ALTR_A10SR_PBDSW_REG:
389787f5e2SThor Thayer 	case ALTR_A10SR_PBDSW_IRQ_REG:
399787f5e2SThor Thayer 	case ALTR_A10SR_PWR_GOOD1_REG:
409787f5e2SThor Thayer 	case ALTR_A10SR_PWR_GOOD2_REG:
419787f5e2SThor Thayer 	case ALTR_A10SR_PWR_GOOD3_REG:
429787f5e2SThor Thayer 	case ALTR_A10SR_FMCAB_REG:
439787f5e2SThor Thayer 	case ALTR_A10SR_HPS_RST_REG:
449787f5e2SThor Thayer 	case ALTR_A10SR_USB_QSPI_REG:
459787f5e2SThor Thayer 	case ALTR_A10SR_SFPA_REG:
469787f5e2SThor Thayer 	case ALTR_A10SR_SFPB_REG:
479787f5e2SThor Thayer 	case ALTR_A10SR_I2C_M_REG:
489787f5e2SThor Thayer 	case ALTR_A10SR_WARM_RST_REG:
499787f5e2SThor Thayer 	case ALTR_A10SR_WR_KEY_REG:
509787f5e2SThor Thayer 	case ALTR_A10SR_PMBUS_REG:
519787f5e2SThor Thayer 		return true;
529787f5e2SThor Thayer 	default:
539787f5e2SThor Thayer 		return false;
549787f5e2SThor Thayer 	}
559787f5e2SThor Thayer }
569787f5e2SThor Thayer 
altr_a10sr_reg_writeable(struct device * dev,unsigned int reg)579787f5e2SThor Thayer static bool altr_a10sr_reg_writeable(struct device *dev, unsigned int reg)
589787f5e2SThor Thayer {
599787f5e2SThor Thayer 	switch (reg) {
609787f5e2SThor Thayer 	case ALTR_A10SR_LED_REG:
619787f5e2SThor Thayer 	case ALTR_A10SR_PBDSW_IRQ_REG:
629787f5e2SThor Thayer 	case ALTR_A10SR_FMCAB_REG:
639787f5e2SThor Thayer 	case ALTR_A10SR_HPS_RST_REG:
649787f5e2SThor Thayer 	case ALTR_A10SR_USB_QSPI_REG:
659787f5e2SThor Thayer 	case ALTR_A10SR_SFPA_REG:
669787f5e2SThor Thayer 	case ALTR_A10SR_SFPB_REG:
679787f5e2SThor Thayer 	case ALTR_A10SR_WARM_RST_REG:
689787f5e2SThor Thayer 	case ALTR_A10SR_WR_KEY_REG:
699787f5e2SThor Thayer 	case ALTR_A10SR_PMBUS_REG:
709787f5e2SThor Thayer 		return true;
719787f5e2SThor Thayer 	default:
729787f5e2SThor Thayer 		return false;
739787f5e2SThor Thayer 	}
749787f5e2SThor Thayer }
759787f5e2SThor Thayer 
altr_a10sr_reg_volatile(struct device * dev,unsigned int reg)769787f5e2SThor Thayer static bool altr_a10sr_reg_volatile(struct device *dev, unsigned int reg)
779787f5e2SThor Thayer {
789787f5e2SThor Thayer 	switch (reg) {
799787f5e2SThor Thayer 	case ALTR_A10SR_PBDSW_REG:
809787f5e2SThor Thayer 	case ALTR_A10SR_PBDSW_IRQ_REG:
819787f5e2SThor Thayer 	case ALTR_A10SR_PWR_GOOD1_REG:
829787f5e2SThor Thayer 	case ALTR_A10SR_PWR_GOOD2_REG:
839787f5e2SThor Thayer 	case ALTR_A10SR_PWR_GOOD3_REG:
849787f5e2SThor Thayer 	case ALTR_A10SR_HPS_RST_REG:
859787f5e2SThor Thayer 	case ALTR_A10SR_I2C_M_REG:
869787f5e2SThor Thayer 	case ALTR_A10SR_WARM_RST_REG:
879787f5e2SThor Thayer 	case ALTR_A10SR_WR_KEY_REG:
889787f5e2SThor Thayer 	case ALTR_A10SR_PMBUS_REG:
899787f5e2SThor Thayer 		return true;
909787f5e2SThor Thayer 	default:
919787f5e2SThor Thayer 		return false;
929787f5e2SThor Thayer 	}
939787f5e2SThor Thayer }
949787f5e2SThor Thayer 
957f70495aSAxel Lin static const struct regmap_config altr_a10sr_regmap_config = {
969787f5e2SThor Thayer 	.reg_bits = 8,
979787f5e2SThor Thayer 	.val_bits = 8,
989787f5e2SThor Thayer 
999787f5e2SThor Thayer 	.cache_type = REGCACHE_NONE,
1009787f5e2SThor Thayer 
1011c96a2f6SDavid Frey 	.use_single_read = true,
1021c96a2f6SDavid Frey 	.use_single_write = true,
1039787f5e2SThor Thayer 	.read_flag_mask = 1,
1049787f5e2SThor Thayer 	.write_flag_mask = 0,
1059787f5e2SThor Thayer 
1069787f5e2SThor Thayer 	.max_register = ALTR_A10SR_WR_KEY_REG,
1079787f5e2SThor Thayer 	.readable_reg = altr_a10sr_reg_readable,
1089787f5e2SThor Thayer 	.writeable_reg = altr_a10sr_reg_writeable,
1099787f5e2SThor Thayer 	.volatile_reg = altr_a10sr_reg_volatile,
1109787f5e2SThor Thayer 
1119787f5e2SThor Thayer };
1129787f5e2SThor Thayer 
altr_a10sr_spi_probe(struct spi_device * spi)1139787f5e2SThor Thayer static int altr_a10sr_spi_probe(struct spi_device *spi)
1149787f5e2SThor Thayer {
1159787f5e2SThor Thayer 	int ret;
1169787f5e2SThor Thayer 	struct altr_a10sr *a10sr;
1179787f5e2SThor Thayer 
1189787f5e2SThor Thayer 	a10sr = devm_kzalloc(&spi->dev, sizeof(*a10sr),
1199787f5e2SThor Thayer 			     GFP_KERNEL);
1209787f5e2SThor Thayer 	if (!a10sr)
1219787f5e2SThor Thayer 		return -ENOMEM;
1229787f5e2SThor Thayer 
1239787f5e2SThor Thayer 	spi->mode = SPI_MODE_3;
1249787f5e2SThor Thayer 	spi->bits_per_word = 8;
1259787f5e2SThor Thayer 	spi_setup(spi);
1269787f5e2SThor Thayer 
1279787f5e2SThor Thayer 	a10sr->dev = &spi->dev;
1289787f5e2SThor Thayer 
1299787f5e2SThor Thayer 	spi_set_drvdata(spi, a10sr);
1309787f5e2SThor Thayer 
1319787f5e2SThor Thayer 	a10sr->regmap = devm_regmap_init_spi(spi, &altr_a10sr_regmap_config);
1329787f5e2SThor Thayer 	if (IS_ERR(a10sr->regmap)) {
1339787f5e2SThor Thayer 		ret = PTR_ERR(a10sr->regmap);
1349787f5e2SThor Thayer 		dev_err(&spi->dev, "Failed to allocate register map: %d\n",
1359787f5e2SThor Thayer 			ret);
1369787f5e2SThor Thayer 		return ret;
1379787f5e2SThor Thayer 	}
1389787f5e2SThor Thayer 
1399787f5e2SThor Thayer 	ret = devm_mfd_add_devices(a10sr->dev, PLATFORM_DEVID_AUTO,
1409787f5e2SThor Thayer 				   altr_a10sr_subdev_info,
1419787f5e2SThor Thayer 				   ARRAY_SIZE(altr_a10sr_subdev_info),
1429787f5e2SThor Thayer 				   NULL, 0, NULL);
1439787f5e2SThor Thayer 	if (ret)
1449787f5e2SThor Thayer 		dev_err(a10sr->dev, "Failed to register sub-devices: %d\n",
1459787f5e2SThor Thayer 			ret);
1469787f5e2SThor Thayer 
1479787f5e2SThor Thayer 	return ret;
1489787f5e2SThor Thayer }
1499787f5e2SThor Thayer 
1509787f5e2SThor Thayer static const struct of_device_id altr_a10sr_spi_of_match[] = {
1519787f5e2SThor Thayer 	{ .compatible = "altr,a10sr" },
1529787f5e2SThor Thayer 	{ },
1539787f5e2SThor Thayer };
1544ea673e8SMark Brown MODULE_DEVICE_TABLE(of, altr_a10sr_spi_of_match);
1554ea673e8SMark Brown 
1564ea673e8SMark Brown static const struct spi_device_id altr_a10sr_spi_ids[] = {
1574ea673e8SMark Brown 	{ .name = "a10sr" },
1584ea673e8SMark Brown 	{ },
1594ea673e8SMark Brown };
1604ea673e8SMark Brown MODULE_DEVICE_TABLE(spi, altr_a10sr_spi_ids);
1619787f5e2SThor Thayer 
1629787f5e2SThor Thayer static struct spi_driver altr_a10sr_spi_driver = {
1639787f5e2SThor Thayer 	.probe = altr_a10sr_spi_probe,
1649787f5e2SThor Thayer 	.driver = {
1659787f5e2SThor Thayer 		.name = "altr_a10sr",
166*23fa9421SZhu Wang 		.of_match_table = altr_a10sr_spi_of_match,
1679787f5e2SThor Thayer 	},
1684ea673e8SMark Brown 	.id_table = altr_a10sr_spi_ids,
1699787f5e2SThor Thayer };
1700a589167SPaul Gortmaker builtin_driver(altr_a10sr_spi_driver, spi_register_driver)
171