162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Driver for the Analog Devices digital potentiometers (SPI bus)
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright (C) 2010-2011 Michael Hennerich, Analog Devices Inc.
662306a36Sopenharmony_ci */
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#include <linux/spi/spi.h>
962306a36Sopenharmony_ci#include <linux/module.h>
1062306a36Sopenharmony_ci
1162306a36Sopenharmony_ci#include "ad525x_dpot.h"
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci/* SPI bus functions */
1462306a36Sopenharmony_cistatic int write8(void *client, u8 val)
1562306a36Sopenharmony_ci{
1662306a36Sopenharmony_ci	u8 data = val;
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ci	return spi_write(client, &data, 1);
1962306a36Sopenharmony_ci}
2062306a36Sopenharmony_ci
2162306a36Sopenharmony_cistatic int write16(void *client, u8 reg, u8 val)
2262306a36Sopenharmony_ci{
2362306a36Sopenharmony_ci	u8 data[2] = {reg, val};
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ci	return spi_write(client, data, 2);
2662306a36Sopenharmony_ci}
2762306a36Sopenharmony_ci
2862306a36Sopenharmony_cistatic int write24(void *client, u8 reg, u16 val)
2962306a36Sopenharmony_ci{
3062306a36Sopenharmony_ci	u8 data[3] = {reg, val >> 8, val};
3162306a36Sopenharmony_ci
3262306a36Sopenharmony_ci	return spi_write(client, data, 3);
3362306a36Sopenharmony_ci}
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_cistatic int read8(void *client)
3662306a36Sopenharmony_ci{
3762306a36Sopenharmony_ci	int ret;
3862306a36Sopenharmony_ci	u8 data;
3962306a36Sopenharmony_ci
4062306a36Sopenharmony_ci	ret = spi_read(client, &data, 1);
4162306a36Sopenharmony_ci	if (ret < 0)
4262306a36Sopenharmony_ci		return ret;
4362306a36Sopenharmony_ci
4462306a36Sopenharmony_ci	return data;
4562306a36Sopenharmony_ci}
4662306a36Sopenharmony_ci
4762306a36Sopenharmony_cistatic int read16(void *client, u8 reg)
4862306a36Sopenharmony_ci{
4962306a36Sopenharmony_ci	int ret;
5062306a36Sopenharmony_ci	u8 buf_rx[2];
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_ci	write16(client, reg, 0);
5362306a36Sopenharmony_ci	ret = spi_read(client, buf_rx, 2);
5462306a36Sopenharmony_ci	if (ret < 0)
5562306a36Sopenharmony_ci		return ret;
5662306a36Sopenharmony_ci
5762306a36Sopenharmony_ci	return (buf_rx[0] << 8) |  buf_rx[1];
5862306a36Sopenharmony_ci}
5962306a36Sopenharmony_ci
6062306a36Sopenharmony_cistatic int read24(void *client, u8 reg)
6162306a36Sopenharmony_ci{
6262306a36Sopenharmony_ci	int ret;
6362306a36Sopenharmony_ci	u8 buf_rx[3];
6462306a36Sopenharmony_ci
6562306a36Sopenharmony_ci	write24(client, reg, 0);
6662306a36Sopenharmony_ci	ret = spi_read(client, buf_rx, 3);
6762306a36Sopenharmony_ci	if (ret < 0)
6862306a36Sopenharmony_ci		return ret;
6962306a36Sopenharmony_ci
7062306a36Sopenharmony_ci	return (buf_rx[1] << 8) |  buf_rx[2];
7162306a36Sopenharmony_ci}
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_cistatic const struct ad_dpot_bus_ops bops = {
7462306a36Sopenharmony_ci	.read_d8	= read8,
7562306a36Sopenharmony_ci	.read_r8d8	= read16,
7662306a36Sopenharmony_ci	.read_r8d16	= read24,
7762306a36Sopenharmony_ci	.write_d8	= write8,
7862306a36Sopenharmony_ci	.write_r8d8	= write16,
7962306a36Sopenharmony_ci	.write_r8d16	= write24,
8062306a36Sopenharmony_ci};
8162306a36Sopenharmony_cistatic int ad_dpot_spi_probe(struct spi_device *spi)
8262306a36Sopenharmony_ci{
8362306a36Sopenharmony_ci	struct ad_dpot_bus_data bdata = {
8462306a36Sopenharmony_ci		.client = spi,
8562306a36Sopenharmony_ci		.bops = &bops,
8662306a36Sopenharmony_ci	};
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_ci	return ad_dpot_probe(&spi->dev, &bdata,
8962306a36Sopenharmony_ci			     spi_get_device_id(spi)->driver_data,
9062306a36Sopenharmony_ci			     spi_get_device_id(spi)->name);
9162306a36Sopenharmony_ci}
9262306a36Sopenharmony_ci
9362306a36Sopenharmony_cistatic void ad_dpot_spi_remove(struct spi_device *spi)
9462306a36Sopenharmony_ci{
9562306a36Sopenharmony_ci	ad_dpot_remove(&spi->dev);
9662306a36Sopenharmony_ci}
9762306a36Sopenharmony_ci
9862306a36Sopenharmony_cistatic const struct spi_device_id ad_dpot_spi_id[] = {
9962306a36Sopenharmony_ci	{"ad5160", AD5160_ID},
10062306a36Sopenharmony_ci	{"ad5161", AD5161_ID},
10162306a36Sopenharmony_ci	{"ad5162", AD5162_ID},
10262306a36Sopenharmony_ci	{"ad5165", AD5165_ID},
10362306a36Sopenharmony_ci	{"ad5200", AD5200_ID},
10462306a36Sopenharmony_ci	{"ad5201", AD5201_ID},
10562306a36Sopenharmony_ci	{"ad5203", AD5203_ID},
10662306a36Sopenharmony_ci	{"ad5204", AD5204_ID},
10762306a36Sopenharmony_ci	{"ad5206", AD5206_ID},
10862306a36Sopenharmony_ci	{"ad5207", AD5207_ID},
10962306a36Sopenharmony_ci	{"ad5231", AD5231_ID},
11062306a36Sopenharmony_ci	{"ad5232", AD5232_ID},
11162306a36Sopenharmony_ci	{"ad5233", AD5233_ID},
11262306a36Sopenharmony_ci	{"ad5235", AD5235_ID},
11362306a36Sopenharmony_ci	{"ad5260", AD5260_ID},
11462306a36Sopenharmony_ci	{"ad5262", AD5262_ID},
11562306a36Sopenharmony_ci	{"ad5263", AD5263_ID},
11662306a36Sopenharmony_ci	{"ad5290", AD5290_ID},
11762306a36Sopenharmony_ci	{"ad5291", AD5291_ID},
11862306a36Sopenharmony_ci	{"ad5292", AD5292_ID},
11962306a36Sopenharmony_ci	{"ad5293", AD5293_ID},
12062306a36Sopenharmony_ci	{"ad7376", AD7376_ID},
12162306a36Sopenharmony_ci	{"ad8400", AD8400_ID},
12262306a36Sopenharmony_ci	{"ad8402", AD8402_ID},
12362306a36Sopenharmony_ci	{"ad8403", AD8403_ID},
12462306a36Sopenharmony_ci	{"adn2850", ADN2850_ID},
12562306a36Sopenharmony_ci	{"ad5270", AD5270_ID},
12662306a36Sopenharmony_ci	{"ad5271", AD5271_ID},
12762306a36Sopenharmony_ci	{}
12862306a36Sopenharmony_ci};
12962306a36Sopenharmony_ciMODULE_DEVICE_TABLE(spi, ad_dpot_spi_id);
13062306a36Sopenharmony_ci
13162306a36Sopenharmony_cistatic struct spi_driver ad_dpot_spi_driver = {
13262306a36Sopenharmony_ci	.driver = {
13362306a36Sopenharmony_ci		.name	= "ad_dpot",
13462306a36Sopenharmony_ci	},
13562306a36Sopenharmony_ci	.probe		= ad_dpot_spi_probe,
13662306a36Sopenharmony_ci	.remove		= ad_dpot_spi_remove,
13762306a36Sopenharmony_ci	.id_table	= ad_dpot_spi_id,
13862306a36Sopenharmony_ci};
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_cimodule_spi_driver(ad_dpot_spi_driver);
14162306a36Sopenharmony_ci
14262306a36Sopenharmony_ciMODULE_AUTHOR("Michael Hennerich <michael.hennerich@analog.com>");
14362306a36Sopenharmony_ciMODULE_DESCRIPTION("digital potentiometer SPI bus driver");
14462306a36Sopenharmony_ciMODULE_LICENSE("GPL");
14562306a36Sopenharmony_ciMODULE_ALIAS("spi:ad_dpot");
146