Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 198294
b: refs/heads/master
c: 6c536e4
h: refs/heads/master
v: v3
  • Loading branch information
Michael Hennerich authored and Linus Torvalds committed May 25, 2010
1 parent 565277f commit 5eecce0
Show file tree
Hide file tree
Showing 7 changed files with 807 additions and 320 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 0c53b9fbcca8870e4f4b248f4ed5fdadd43a01b6
refs/heads/master: 6c536e4ce8edd61fdc4ab68e19ae164a54fc958f
30 changes: 27 additions & 3 deletions trunk/drivers/misc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -14,11 +14,15 @@ menuconfig MISC_DEVICES
if MISC_DEVICES

config AD525X_DPOT
tristate "Analog Devices AD525x Digital Potentiometers"
depends on I2C && SYSFS
tristate "Analog Devices Digital Potentiometers"
depends on (I2C || SPI) && SYSFS
help
If you say yes here, you get support for the Analog Devices
AD5258, AD5259, AD5251, AD5252, AD5253, AD5254 and AD5255
AD5258, AD5259, AD5251, AD5252, AD5253, AD5254, AD5255
AD5160, AD5161, AD5162, AD5165, AD5200, AD5201, AD5203,
AD5204, AD5206, AD5207, AD5231, AD5232, AD5233, AD5235,
AD5260, AD5262, AD5263, AD5290, AD5291, AD5292, AD5293,
AD7376, AD8400, AD8402, AD8403, ADN2850
digital potentiometer chips.

See Documentation/misc-devices/ad525x_dpot.txt for the
Expand All @@ -27,6 +31,26 @@ config AD525X_DPOT
This driver can also be built as a module. If so, the module
will be called ad525x_dpot.

config AD525X_DPOT_I2C
tristate "support I2C bus connection"
depends on AD525X_DPOT && I2C
help
Say Y here if you have a digital potentiometers hooked to an I2C bus.

To compile this driver as a module, choose M here: the
module will be called ad525x_dpot-i2c.

config AD525X_DPOT_SPI
tristate "support SPI bus connection"
depends on AD525X_DPOT && SPI_MASTER
help
Say Y here if you have a digital potentiometers hooked to an SPI bus.

If unsure, say N (but it's safe to say "Y").

To compile this driver as a module, choose M here: the
module will be called ad525x_dpot-spi.

config ATMEL_PWM
tristate "Atmel AT32/AT91 PWM support"
depends on AVR32 || ARCH_AT91SAM9263 || ARCH_AT91SAM9RL || ARCH_AT91CAP9
Expand Down
2 changes: 2 additions & 0 deletions trunk/drivers/misc/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

obj-$(CONFIG_IBM_ASM) += ibmasm/
obj-$(CONFIG_AD525X_DPOT) += ad525x_dpot.o
obj-$(CONFIG_AD525X_DPOT_I2C) += ad525x_dpot-i2c.o
obj-$(CONFIG_AD525X_DPOT_SPI) += ad525x_dpot-spi.o
obj-$(CONFIG_ATMEL_PWM) += atmel_pwm.o
obj-$(CONFIG_ATMEL_SSC) += atmel-ssc.o
obj-$(CONFIG_ATMEL_TCLIB) += atmel_tclib.o
Expand Down
119 changes: 119 additions & 0 deletions trunk/drivers/misc/ad525x_dpot-i2c.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
/*
* Driver for the Analog Devices digital potentiometers (I2C bus)
*
* Copyright (C) 2010 Michael Hennerich, Analog Devices Inc.
*
* Licensed under the GPL-2 or later.
*/

#include <linux/i2c.h>
#include <linux/module.h>

#include "ad525x_dpot.h"

/* ------------------------------------------------------------------------- */
/* I2C bus functions */
static int write_d8(void *client, u8 val)
{
return i2c_smbus_write_byte(client, val);
}

static int write_r8d8(void *client, u8 reg, u8 val)
{
return i2c_smbus_write_byte_data(client, reg, val);
}

static int write_r8d16(void *client, u8 reg, u16 val)
{
return i2c_smbus_write_word_data(client, reg, val);
}

static int read_d8(void *client)
{
return i2c_smbus_read_byte(client);
}

static int read_r8d8(void *client, u8 reg)
{
return i2c_smbus_read_byte_data(client, reg);
}

static int read_r8d16(void *client, u8 reg)
{
return i2c_smbus_read_word_data(client, reg);
}

static const struct ad_dpot_bus_ops bops = {
.read_d8 = read_d8,
.read_r8d8 = read_r8d8,
.read_r8d16 = read_r8d16,
.write_d8 = write_d8,
.write_r8d8 = write_r8d8,
.write_r8d16 = write_r8d16,
};

static int __devinit ad_dpot_i2c_probe(struct i2c_client *client,
const struct i2c_device_id *id)
{
struct ad_dpot_bus_data bdata = {
.client = client,
.bops = &bops,
};

struct ad_dpot_id dpot_id = {
.name = (char *) &id->name,
.devid = id->driver_data,
};

if (!i2c_check_functionality(client->adapter,
I2C_FUNC_SMBUS_WORD_DATA)) {
dev_err(&client->dev, "SMBUS Word Data not Supported\n");
return -EIO;
}

return ad_dpot_probe(&client->dev, &bdata, &dpot_id);
}

static int __devexit ad_dpot_i2c_remove(struct i2c_client *client)
{
return ad_dpot_remove(&client->dev);
}

static const struct i2c_device_id ad_dpot_id[] = {
{"ad5258", AD5258_ID},
{"ad5259", AD5259_ID},
{"ad5251", AD5251_ID},
{"ad5252", AD5252_ID},
{"ad5253", AD5253_ID},
{"ad5254", AD5254_ID},
{"ad5255", AD5255_ID},
{}
};
MODULE_DEVICE_TABLE(i2c, ad_dpot_id);

static struct i2c_driver ad_dpot_i2c_driver = {
.driver = {
.name = "ad_dpot",
.owner = THIS_MODULE,
},
.probe = ad_dpot_i2c_probe,
.remove = __devexit_p(ad_dpot_i2c_remove),
.id_table = ad_dpot_id,
};

static int __init ad_dpot_i2c_init(void)
{
return i2c_add_driver(&ad_dpot_i2c_driver);
}
module_init(ad_dpot_i2c_init);

static void __exit ad_dpot_i2c_exit(void)
{
i2c_del_driver(&ad_dpot_i2c_driver);
}
module_exit(ad_dpot_i2c_exit);

MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
MODULE_DESCRIPTION("digital potentiometer I2C bus driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("i2c:ad_dpot");
172 changes: 172 additions & 0 deletions trunk/drivers/misc/ad525x_dpot-spi.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,172 @@
/*
* Driver for the Analog Devices digital potentiometers (SPI bus)
*
* Copyright (C) 2010 Michael Hennerich, Analog Devices Inc.
*
* Licensed under the GPL-2 or later.
*/

#include <linux/spi/spi.h>
#include <linux/module.h>

#include "ad525x_dpot.h"

static const struct ad_dpot_id ad_dpot_spi_devlist[] = {
{.name = "ad5160", .devid = AD5160_ID},
{.name = "ad5161", .devid = AD5161_ID},
{.name = "ad5162", .devid = AD5162_ID},
{.name = "ad5165", .devid = AD5165_ID},
{.name = "ad5200", .devid = AD5200_ID},
{.name = "ad5201", .devid = AD5201_ID},
{.name = "ad5203", .devid = AD5203_ID},
{.name = "ad5204", .devid = AD5204_ID},
{.name = "ad5206", .devid = AD5206_ID},
{.name = "ad5207", .devid = AD5207_ID},
{.name = "ad5231", .devid = AD5231_ID},
{.name = "ad5232", .devid = AD5232_ID},
{.name = "ad5233", .devid = AD5233_ID},
{.name = "ad5235", .devid = AD5235_ID},
{.name = "ad5260", .devid = AD5260_ID},
{.name = "ad5262", .devid = AD5262_ID},
{.name = "ad5263", .devid = AD5263_ID},
{.name = "ad5290", .devid = AD5290_ID},
{.name = "ad5291", .devid = AD5291_ID},
{.name = "ad5292", .devid = AD5292_ID},
{.name = "ad5293", .devid = AD5293_ID},
{.name = "ad7376", .devid = AD7376_ID},
{.name = "ad8400", .devid = AD8400_ID},
{.name = "ad8402", .devid = AD8402_ID},
{.name = "ad8403", .devid = AD8403_ID},
{.name = "adn2850", .devid = ADN2850_ID},
{}
};

/* ------------------------------------------------------------------------- */

/* SPI bus functions */
static int write8(void *client, u8 val)
{
u8 data = val;
return spi_write(client, &data, 1);
}

static int write16(void *client, u8 reg, u8 val)
{
u8 data[2] = {reg, val};
return spi_write(client, data, 1);
}

static int write24(void *client, u8 reg, u16 val)
{
u8 data[3] = {reg, val >> 8, val};
return spi_write(client, data, 1);
}

static int read8(void *client)
{
int ret;
u8 data;
ret = spi_read(client, &data, 1);
if (ret < 0)
return ret;

return data;
}

static int read16(void *client, u8 reg)
{
int ret;
u8 buf_rx[2];

write16(client, reg, 0);
ret = spi_read(client, buf_rx, 2);
if (ret < 0)
return ret;

return (buf_rx[0] << 8) | buf_rx[1];
}

static int read24(void *client, u8 reg)
{
int ret;
u8 buf_rx[3];

write24(client, reg, 0);
ret = spi_read(client, buf_rx, 3);
if (ret < 0)
return ret;

return (buf_rx[1] << 8) | buf_rx[2];
}

static const struct ad_dpot_bus_ops bops = {
.read_d8 = read8,
.read_r8d8 = read16,
.read_r8d16 = read24,
.write_d8 = write8,
.write_r8d8 = write16,
.write_r8d16 = write24,
};

static const struct ad_dpot_id *dpot_match_id(const struct ad_dpot_id *id,
char *name)
{
while (id->name && id->name[0]) {
if (strcmp(name, id->name) == 0)
return id;
id++;
}
return NULL;
}

static int __devinit ad_dpot_spi_probe(struct spi_device *spi)
{
char *name = spi->dev.platform_data;
const struct ad_dpot_id *dpot_id;

struct ad_dpot_bus_data bdata = {
.client = spi,
.bops = &bops,
};

dpot_id = dpot_match_id(ad_dpot_spi_devlist, name);

if (dpot_id == NULL) {
dev_err(&spi->dev, "%s not in supported device list", name);
return -ENODEV;
}

return ad_dpot_probe(&spi->dev, &bdata, dpot_id);
}

static int __devexit ad_dpot_spi_remove(struct spi_device *spi)
{
return ad_dpot_remove(&spi->dev);
}

static struct spi_driver ad_dpot_spi_driver = {
.driver = {
.name = "ad_dpot",
.bus = &spi_bus_type,
.owner = THIS_MODULE,
},
.probe = ad_dpot_spi_probe,
.remove = __devexit_p(ad_dpot_spi_remove),
};

static int __init ad_dpot_spi_init(void)
{
return spi_register_driver(&ad_dpot_spi_driver);
}
module_init(ad_dpot_spi_init);

static void __exit ad_dpot_spi_exit(void)
{
spi_unregister_driver(&ad_dpot_spi_driver);
}
module_exit(ad_dpot_spi_exit);

MODULE_AUTHOR("Michael Hennerich <hennerich@blackfin.uclinux.org>");
MODULE_DESCRIPTION("digital potentiometer SPI bus driver");
MODULE_LICENSE("GPL");
MODULE_ALIAS("spi:ad_dpot");
Loading

0 comments on commit 5eecce0

Please sign in to comment.