brintos

brintos / linux-shallow public Read only

0
0
Text · 3.8 KiB · 4838d2e Raw
158 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * max5487.c - Support for MAX5487, MAX5488, MAX5489 digital potentiometers4 *5 * Copyright (C) 2016 Cristina-Gabriela Moraru <cristina.moraru09@gmail.com>6 */7#include <linux/module.h>8#include <linux/mod_devicetable.h>9#include <linux/spi/spi.h>10 11#include <linux/iio/sysfs.h>12#include <linux/iio/iio.h>13 14#define MAX5487_WRITE_WIPER_A	(0x01 << 8)15#define MAX5487_WRITE_WIPER_B	(0x02 << 8)16 17/* copy both wiper regs to NV regs */18#define MAX5487_COPY_AB_TO_NV	(0x23 << 8)19/* copy both NV regs to wiper regs */20#define MAX5487_COPY_NV_TO_AB	(0x33 << 8)21 22#define MAX5487_MAX_POS		25523 24struct max5487_data {25	struct spi_device *spi;26	int kohms;27};28 29#define MAX5487_CHANNEL(ch, addr) {				\30	.type = IIO_RESISTANCE,					\31	.indexed = 1,						\32	.output = 1,						\33	.channel = ch,						\34	.address = addr,					\35	.info_mask_separate = BIT(IIO_CHAN_INFO_RAW),		\36	.info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE),	\37}38 39static const struct iio_chan_spec max5487_channels[] = {40	MAX5487_CHANNEL(0, MAX5487_WRITE_WIPER_A),41	MAX5487_CHANNEL(1, MAX5487_WRITE_WIPER_B),42};43 44static int max5487_write_cmd(struct spi_device *spi, u16 cmd)45{46	return spi_write(spi, (const void *) &cmd, sizeof(u16));47}48 49static int max5487_read_raw(struct iio_dev *indio_dev,50			    struct iio_chan_spec const *chan,51			    int *val, int *val2, long mask)52{53	struct max5487_data *data = iio_priv(indio_dev);54 55	if (mask != IIO_CHAN_INFO_SCALE)56		return -EINVAL;57 58	*val = 1000 * data->kohms;59	*val2 = MAX5487_MAX_POS;60 61	return IIO_VAL_FRACTIONAL;62}63 64static int max5487_write_raw(struct iio_dev *indio_dev,65			     struct iio_chan_spec const *chan,66			     int val, int val2, long mask)67{68	struct max5487_data *data = iio_priv(indio_dev);69 70	if (mask != IIO_CHAN_INFO_RAW)71		return -EINVAL;72 73	if (val < 0 || val > MAX5487_MAX_POS)74		return -EINVAL;75 76	return max5487_write_cmd(data->spi, chan->address | val);77}78 79static const struct iio_info max5487_info = {80	.read_raw = max5487_read_raw,81	.write_raw = max5487_write_raw,82};83 84static int max5487_spi_probe(struct spi_device *spi)85{86	struct iio_dev *indio_dev;87	struct max5487_data *data;88	const struct spi_device_id *id = spi_get_device_id(spi);89	int ret;90 91	indio_dev = devm_iio_device_alloc(&spi->dev, sizeof(*data));92	if (!indio_dev)93		return -ENOMEM;94 95	spi_set_drvdata(spi, indio_dev);96	data = iio_priv(indio_dev);97 98	data->spi = spi;99	data->kohms = id->driver_data;100 101	indio_dev->info = &max5487_info;102	indio_dev->name = id->name;103	indio_dev->modes = INDIO_DIRECT_MODE;104	indio_dev->channels = max5487_channels;105	indio_dev->num_channels = ARRAY_SIZE(max5487_channels);106 107	/* restore both wiper regs from NV regs */108	ret = max5487_write_cmd(data->spi, MAX5487_COPY_NV_TO_AB);109	if (ret < 0)110		return ret;111 112	return iio_device_register(indio_dev);113}114 115static void max5487_spi_remove(struct spi_device *spi)116{117	struct iio_dev *indio_dev = spi_get_drvdata(spi);118	int ret;119 120	iio_device_unregister(indio_dev);121 122	/* save both wiper regs to NV regs */123	ret = max5487_write_cmd(spi, MAX5487_COPY_AB_TO_NV);124	if (ret)125		dev_warn(&spi->dev, "Failed to save wiper regs to NV regs\n");126}127 128static const struct spi_device_id max5487_id[] = {129	{ "MAX5487", 10 },130	{ "MAX5488", 50 },131	{ "MAX5489", 100 },132	{ }133};134MODULE_DEVICE_TABLE(spi, max5487_id);135 136static const struct acpi_device_id max5487_acpi_match[] = {137	{ "MAX5487", 10 },138	{ "MAX5488", 50 },139	{ "MAX5489", 100 },140	{ },141};142MODULE_DEVICE_TABLE(acpi, max5487_acpi_match);143 144static struct spi_driver max5487_driver = {145	.driver = {146		.name = "max5487",147		.acpi_match_table = max5487_acpi_match,148	},149	.id_table = max5487_id,150	.probe = max5487_spi_probe,151	.remove = max5487_spi_remove152};153module_spi_driver(max5487_driver);154 155MODULE_AUTHOR("Cristina-Gabriela Moraru <cristina.moraru09@gmail.com>");156MODULE_DESCRIPTION("max5487 SPI driver");157MODULE_LICENSE("GPL v2");158