brintos

brintos / linux-shallow public Read only

0
0
Text · 5.4 KiB · 1c6652f Raw
252 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Microchip ksz series register access through SPI4 *5 * Copyright (C) 2017-2024 Microchip Technology Inc.6 *	Tristram Ha <Tristram.Ha@microchip.com>7 */8 9#include <linux/unaligned.h>10 11#include <linux/delay.h>12#include <linux/kernel.h>13#include <linux/module.h>14#include <linux/regmap.h>15#include <linux/spi/spi.h>16 17#include "ksz_common.h"18 19#define KSZ8795_SPI_ADDR_SHIFT			1220#define KSZ8795_SPI_ADDR_ALIGN			321#define KSZ8795_SPI_TURNAROUND_SHIFT		122 23#define KSZ8863_SPI_ADDR_SHIFT			824#define KSZ8863_SPI_ADDR_ALIGN			825#define KSZ8863_SPI_TURNAROUND_SHIFT		026 27#define KSZ9477_SPI_ADDR_SHIFT			2428#define KSZ9477_SPI_ADDR_ALIGN			329#define KSZ9477_SPI_TURNAROUND_SHIFT		530 31KSZ_REGMAP_TABLE(ksz8795, 16, KSZ8795_SPI_ADDR_SHIFT,32		 KSZ8795_SPI_TURNAROUND_SHIFT, KSZ8795_SPI_ADDR_ALIGN);33 34KSZ_REGMAP_TABLE(ksz8863, 16, KSZ8863_SPI_ADDR_SHIFT,35		 KSZ8863_SPI_TURNAROUND_SHIFT, KSZ8863_SPI_ADDR_ALIGN);36 37KSZ_REGMAP_TABLE(ksz9477, 32, KSZ9477_SPI_ADDR_SHIFT,38		 KSZ9477_SPI_TURNAROUND_SHIFT, KSZ9477_SPI_ADDR_ALIGN);39 40static int ksz_spi_probe(struct spi_device *spi)41{42	const struct regmap_config *regmap_config;43	const struct ksz_chip_data *chip;44	struct device *ddev = &spi->dev;45	struct regmap_config rc;46	struct ksz_device *dev;47	int i, ret = 0;48 49	dev = ksz_switch_alloc(&spi->dev, spi);50	if (!dev)51		return -ENOMEM;52 53	chip = device_get_match_data(ddev);54	if (!chip)55		return -EINVAL;56 57	if (chip->chip_id == KSZ88X3_CHIP_ID)58		regmap_config = ksz8863_regmap_config;59	else if (chip->chip_id == KSZ8795_CHIP_ID ||60		 chip->chip_id == KSZ8794_CHIP_ID ||61		 chip->chip_id == KSZ8765_CHIP_ID)62		regmap_config = ksz8795_regmap_config;63	else if (chip->chip_id == KSZ8895_CHIP_ID ||64		 chip->chip_id == KSZ8864_CHIP_ID)65		regmap_config = ksz8863_regmap_config;66	else67		regmap_config = ksz9477_regmap_config;68 69	for (i = 0; i < __KSZ_NUM_REGMAPS; i++) {70		rc = regmap_config[i];71		rc.lock_arg = &dev->regmap_mutex;72		rc.wr_table = chip->wr_table;73		rc.rd_table = chip->rd_table;74		dev->regmap[i] = devm_regmap_init_spi(spi, &rc);75 76		if (IS_ERR(dev->regmap[i])) {77			return dev_err_probe(&spi->dev, PTR_ERR(dev->regmap[i]),78					     "Failed to initialize regmap%i\n",79					     regmap_config[i].val_bits);80		}81	}82 83	if (spi->dev.platform_data)84		dev->pdata = spi->dev.platform_data;85 86	/* setup spi */87	spi->mode = SPI_MODE_3;88	ret = spi_setup(spi);89	if (ret)90		return ret;91 92	dev->irq = spi->irq;93 94	ret = ksz_switch_register(dev);95 96	/* Main DSA driver may not be started yet. */97	if (ret)98		return ret;99 100	spi_set_drvdata(spi, dev);101 102	return 0;103}104 105static void ksz_spi_remove(struct spi_device *spi)106{107	struct ksz_device *dev = spi_get_drvdata(spi);108 109	if (dev)110		ksz_switch_remove(dev);111}112 113static void ksz_spi_shutdown(struct spi_device *spi)114{115	struct ksz_device *dev = spi_get_drvdata(spi);116 117	if (!dev)118		return;119 120	ksz_switch_shutdown(dev);121 122	spi_set_drvdata(spi, NULL);123}124 125static const struct of_device_id ksz_dt_ids[] = {126	{127		.compatible = "microchip,ksz8765",128		.data = &ksz_switch_chips[KSZ8765]129	},130	{131		.compatible = "microchip,ksz8794",132		.data = &ksz_switch_chips[KSZ8794]133	},134	{135		.compatible = "microchip,ksz8795",136		.data = &ksz_switch_chips[KSZ8795]137	},138	{139		.compatible = "microchip,ksz8863",140		.data = &ksz_switch_chips[KSZ88X3]141	},142	{143		.compatible = "microchip,ksz8864",144		.data = &ksz_switch_chips[KSZ8864]145	},146	{147		.compatible = "microchip,ksz8873",148		.data = &ksz_switch_chips[KSZ88X3]149	},150	{151		.compatible = "microchip,ksz8895",152		.data = &ksz_switch_chips[KSZ8895]153	},154	{155		.compatible = "microchip,ksz9477",156		.data = &ksz_switch_chips[KSZ9477]157	},158	{159		.compatible = "microchip,ksz9896",160		.data = &ksz_switch_chips[KSZ9896]161	},162	{163		.compatible = "microchip,ksz9897",164		.data = &ksz_switch_chips[KSZ9897]165	},166	{167		.compatible = "microchip,ksz9893",168		.data = &ksz_switch_chips[KSZ9893]169	},170	{171		.compatible = "microchip,ksz9563",172		.data = &ksz_switch_chips[KSZ9563]173	},174	{175		.compatible = "microchip,ksz8563",176		.data = &ksz_switch_chips[KSZ8563]177	},178	{179		.compatible = "microchip,ksz8567",180		.data = &ksz_switch_chips[KSZ8567]181	},182	{183		.compatible = "microchip,ksz9567",184		.data = &ksz_switch_chips[KSZ9567]185	},186	{187		.compatible = "microchip,lan9370",188		.data = &ksz_switch_chips[LAN9370]189	},190	{191		.compatible = "microchip,lan9371",192		.data = &ksz_switch_chips[LAN9371]193	},194	{195		.compatible = "microchip,lan9372",196		.data = &ksz_switch_chips[LAN9372]197	},198	{199		.compatible = "microchip,lan9373",200		.data = &ksz_switch_chips[LAN9373]201	},202	{203		.compatible = "microchip,lan9374",204		.data = &ksz_switch_chips[LAN9374]205	},206	{},207};208MODULE_DEVICE_TABLE(of, ksz_dt_ids);209 210static const struct spi_device_id ksz_spi_ids[] = {211	{ "ksz8765" },212	{ "ksz8794" },213	{ "ksz8795" },214	{ "ksz8863" },215	{ "ksz8864" },216	{ "ksz8873" },217	{ "ksz8895" },218	{ "ksz9477" },219	{ "ksz9896" },220	{ "ksz9897" },221	{ "ksz9893" },222	{ "ksz9563" },223	{ "ksz8563" },224	{ "ksz8567" },225	{ "ksz9567" },226	{ "lan9370" },227	{ "lan9371" },228	{ "lan9372" },229	{ "lan9373" },230	{ "lan9374" },231	{ },232};233MODULE_DEVICE_TABLE(spi, ksz_spi_ids);234 235static struct spi_driver ksz_spi_driver = {236	.driver = {237		.name	= "ksz-switch",238		.of_match_table = ksz_dt_ids,239	},240	.id_table = ksz_spi_ids,241	.probe	= ksz_spi_probe,242	.remove	= ksz_spi_remove,243	.shutdown = ksz_spi_shutdown,244};245 246module_spi_driver(ksz_spi_driver);247 248MODULE_ALIAS("spi:lan937x");249MODULE_AUTHOR("Tristram Ha <Tristram.Ha@microchip.com>");250MODULE_DESCRIPTION("Microchip ksz Series Switch SPI Driver");251MODULE_LICENSE("GPL");252