162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-only
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * EEPROMs access control driver for display configuration EEPROMs
462306a36Sopenharmony_ci * on DigsyMTC board.
562306a36Sopenharmony_ci *
662306a36Sopenharmony_ci * (C) 2011 DENX Software Engineering, Anatolij Gustschin <agust@denx.de>
762306a36Sopenharmony_ci *
862306a36Sopenharmony_ci * FIXME: this driver is used on a device-tree probed platform: it
962306a36Sopenharmony_ci * should be defined as a bit-banged SPI device and probed from the device
1062306a36Sopenharmony_ci * tree and not like this with static grabbing of a few numbered GPIO
1162306a36Sopenharmony_ci * lines at random.
1262306a36Sopenharmony_ci *
1362306a36Sopenharmony_ci * Add proper SPI and EEPROM in arch/powerpc/boot/dts/digsy_mtc.dts
1462306a36Sopenharmony_ci * and delete this driver.
1562306a36Sopenharmony_ci */
1662306a36Sopenharmony_ci
1762306a36Sopenharmony_ci#include <linux/gpio.h>
1862306a36Sopenharmony_ci#include <linux/gpio/machine.h>
1962306a36Sopenharmony_ci#include <linux/init.h>
2062306a36Sopenharmony_ci#include <linux/platform_device.h>
2162306a36Sopenharmony_ci#include <linux/spi/spi.h>
2262306a36Sopenharmony_ci#include <linux/spi/spi_gpio.h>
2362306a36Sopenharmony_ci#include <linux/eeprom_93xx46.h>
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ci#define GPIO_EEPROM_CLK		216
2662306a36Sopenharmony_ci#define GPIO_EEPROM_CS		210
2762306a36Sopenharmony_ci#define GPIO_EEPROM_DI		217
2862306a36Sopenharmony_ci#define GPIO_EEPROM_DO		249
2962306a36Sopenharmony_ci#define GPIO_EEPROM_OE		255
3062306a36Sopenharmony_ci#define EE_SPI_BUS_NUM	1
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_cistatic void digsy_mtc_op_prepare(void *p)
3362306a36Sopenharmony_ci{
3462306a36Sopenharmony_ci	/* enable */
3562306a36Sopenharmony_ci	gpio_set_value(GPIO_EEPROM_OE, 0);
3662306a36Sopenharmony_ci}
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_cistatic void digsy_mtc_op_finish(void *p)
3962306a36Sopenharmony_ci{
4062306a36Sopenharmony_ci	/* disable */
4162306a36Sopenharmony_ci	gpio_set_value(GPIO_EEPROM_OE, 1);
4262306a36Sopenharmony_ci}
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_cistruct eeprom_93xx46_platform_data digsy_mtc_eeprom_data = {
4562306a36Sopenharmony_ci	.flags		= EE_ADDR8,
4662306a36Sopenharmony_ci	.prepare	= digsy_mtc_op_prepare,
4762306a36Sopenharmony_ci	.finish		= digsy_mtc_op_finish,
4862306a36Sopenharmony_ci};
4962306a36Sopenharmony_ci
5062306a36Sopenharmony_cistatic struct spi_gpio_platform_data eeprom_spi_gpio_data = {
5162306a36Sopenharmony_ci	.num_chipselect	= 1,
5262306a36Sopenharmony_ci};
5362306a36Sopenharmony_ci
5462306a36Sopenharmony_cistatic struct platform_device digsy_mtc_eeprom = {
5562306a36Sopenharmony_ci	.name	= "spi_gpio",
5662306a36Sopenharmony_ci	.id	= EE_SPI_BUS_NUM,
5762306a36Sopenharmony_ci	.dev	= {
5862306a36Sopenharmony_ci		.platform_data	= &eeprom_spi_gpio_data,
5962306a36Sopenharmony_ci	},
6062306a36Sopenharmony_ci};
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_cistatic struct gpiod_lookup_table eeprom_spi_gpiod_table = {
6362306a36Sopenharmony_ci	.dev_id         = "spi_gpio",
6462306a36Sopenharmony_ci	.table          = {
6562306a36Sopenharmony_ci		GPIO_LOOKUP("gpio@b00", GPIO_EEPROM_CLK,
6662306a36Sopenharmony_ci			    "sck", GPIO_ACTIVE_HIGH),
6762306a36Sopenharmony_ci		GPIO_LOOKUP("gpio@b00", GPIO_EEPROM_DI,
6862306a36Sopenharmony_ci			    "mosi", GPIO_ACTIVE_HIGH),
6962306a36Sopenharmony_ci		GPIO_LOOKUP("gpio@b00", GPIO_EEPROM_DO,
7062306a36Sopenharmony_ci			    "miso", GPIO_ACTIVE_HIGH),
7162306a36Sopenharmony_ci		GPIO_LOOKUP("gpio@b00", GPIO_EEPROM_CS,
7262306a36Sopenharmony_ci			    "cs", GPIO_ACTIVE_HIGH),
7362306a36Sopenharmony_ci		{ },
7462306a36Sopenharmony_ci	},
7562306a36Sopenharmony_ci};
7662306a36Sopenharmony_ci
7762306a36Sopenharmony_cistatic struct spi_board_info digsy_mtc_eeprom_info[] __initdata = {
7862306a36Sopenharmony_ci	{
7962306a36Sopenharmony_ci		.modalias		= "93xx46",
8062306a36Sopenharmony_ci		.max_speed_hz		= 1000000,
8162306a36Sopenharmony_ci		.bus_num		= EE_SPI_BUS_NUM,
8262306a36Sopenharmony_ci		.chip_select		= 0,
8362306a36Sopenharmony_ci		.mode			= SPI_MODE_0,
8462306a36Sopenharmony_ci		.platform_data		= &digsy_mtc_eeprom_data,
8562306a36Sopenharmony_ci	},
8662306a36Sopenharmony_ci};
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_cistatic int __init digsy_mtc_eeprom_devices_init(void)
8962306a36Sopenharmony_ci{
9062306a36Sopenharmony_ci	int ret;
9162306a36Sopenharmony_ci
9262306a36Sopenharmony_ci	ret = gpio_request_one(GPIO_EEPROM_OE, GPIOF_OUT_INIT_HIGH,
9362306a36Sopenharmony_ci				"93xx46 EEPROMs OE");
9462306a36Sopenharmony_ci	if (ret) {
9562306a36Sopenharmony_ci		pr_err("can't request gpio %d\n", GPIO_EEPROM_OE);
9662306a36Sopenharmony_ci		return ret;
9762306a36Sopenharmony_ci	}
9862306a36Sopenharmony_ci	gpiod_add_lookup_table(&eeprom_spi_gpiod_table);
9962306a36Sopenharmony_ci	spi_register_board_info(digsy_mtc_eeprom_info,
10062306a36Sopenharmony_ci				ARRAY_SIZE(digsy_mtc_eeprom_info));
10162306a36Sopenharmony_ci	return platform_device_register(&digsy_mtc_eeprom);
10262306a36Sopenharmony_ci}
10362306a36Sopenharmony_cidevice_initcall(digsy_mtc_eeprom_devices_init);
104