aboutsummaryrefslogtreecommitdiffstats
path: root/recipes-kernel/linux/linux-handheld-4.0/locomo/0001-iio-add-m62332-DAC-driver.patch
diff options
context:
space:
mode:
Diffstat (limited to 'recipes-kernel/linux/linux-handheld-4.0/locomo/0001-iio-add-m62332-DAC-driver.patch')
-rw-r--r--recipes-kernel/linux/linux-handheld-4.0/locomo/0001-iio-add-m62332-DAC-driver.patch295
1 files changed, 295 insertions, 0 deletions
diff --git a/recipes-kernel/linux/linux-handheld-4.0/locomo/0001-iio-add-m62332-DAC-driver.patch b/recipes-kernel/linux/linux-handheld-4.0/locomo/0001-iio-add-m62332-DAC-driver.patch
new file mode 100644
index 0000000..d1cf814
--- /dev/null
+++ b/recipes-kernel/linux/linux-handheld-4.0/locomo/0001-iio-add-m62332-DAC-driver.patch
@@ -0,0 +1,295 @@
+From 879c0ec1131e472f752d70ddf117dcabaf8ea106 Mon Sep 17 00:00:00 2001
+From: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
+Date: Sun, 23 Nov 2014 18:42:52 +0300
+Subject: [PATCH 01/20] iio: add m62332 DAC driver
+
+m62332 is a simple 2-channel DAC used on several Sharp Zaurus boards to
+control LCD voltage, backlight and sound. The driver use regulators to
+control the reference voltage and enabling/disabling the DAC.
+
+Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
+---
+ drivers/iio/dac/Kconfig | 10 ++
+ drivers/iio/dac/Makefile | 1 +
+ drivers/iio/dac/m62332.c | 236 +++++++++++++++++++++++++++++++++++++++++++++++
+ 3 files changed, 247 insertions(+)
+ create mode 100644 drivers/iio/dac/m62332.c
+
+diff --git a/drivers/iio/dac/Kconfig b/drivers/iio/dac/Kconfig
+index 2236ea2..2ede061 100644
+--- a/drivers/iio/dac/Kconfig
++++ b/drivers/iio/dac/Kconfig
+@@ -142,6 +142,16 @@ config AD7303
+ To compile this driver as module choose M here: the module will be called
+ ad7303.
+
++config M62332
++ tristate "Mitsubishi M62332 DAC driver"
++ depends on I2C
++ help
++ If you say yes here you get support for the Mitsubishi M62332
++ (I2C 8-Bit DACs with rail-to-rail outputs).
++
++ This driver can also be built as a module. If so, the module
++ will be called m62332.
++
+ config MAX517
+ tristate "Maxim MAX517/518/519 DAC driver"
+ depends on I2C
+diff --git a/drivers/iio/dac/Makefile b/drivers/iio/dac/Makefile
+index 52be7e1..63ae056 100644
+--- a/drivers/iio/dac/Makefile
++++ b/drivers/iio/dac/Makefile
+@@ -16,6 +16,7 @@ obj-$(CONFIG_AD5764) += ad5764.o
+ obj-$(CONFIG_AD5791) += ad5791.o
+ obj-$(CONFIG_AD5686) += ad5686.o
+ obj-$(CONFIG_AD7303) += ad7303.o
++obj-$(CONFIG_M62332) += m62332.o
+ obj-$(CONFIG_MAX517) += max517.o
+ obj-$(CONFIG_MAX5821) += max5821.o
+ obj-$(CONFIG_MCP4725) += mcp4725.o
+diff --git a/drivers/iio/dac/m62332.c b/drivers/iio/dac/m62332.c
+new file mode 100644
+index 0000000..90574d7
+--- /dev/null
++++ b/drivers/iio/dac/m62332.c
+@@ -0,0 +1,236 @@
++/*
++ * m62332.c - Support for Mitsubishi m62332 DAC
++ *
++ * Copyright (c) 2014 Dmitry Eremin-Solenikov
++ *
++ * Based on max517 driver:
++ * Copyright (C) 2010, 2011 Roland Stigge <stigge@antcom.de>
++ *
++ * This program is free software; you can redistribute it and/or modify
++ * it under the terms of the GNU General Public License as published by
++ * the Free Software Foundation; either version 2 of the License, or
++ * (at your option) any later version.
++ *
++ * This program is distributed in the hope that it will be useful,
++ * but WITHOUT ANY WARRANTY; without even the implied warranty of
++ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
++ * GNU General Public License for more details.
++ */
++
++#include <linux/module.h>
++#include <linux/slab.h>
++#include <linux/jiffies.h>
++#include <linux/i2c.h>
++#include <linux/err.h>
++
++#include <linux/iio/iio.h>
++#include <linux/iio/driver.h>
++
++#include <linux/regulator/consumer.h>
++
++struct m62332_data {
++ struct i2c_client *client;
++ unsigned short vref_mv;
++ unsigned char raw[2];
++ struct regulator *vcc;
++#ifdef CONFIG_PM_SLEEP
++ unsigned char save[2];
++#endif
++};
++
++static int m62332_set_value(struct iio_dev *indio_dev,
++ unsigned char val, int channel)
++{
++ struct m62332_data *data = iio_priv(indio_dev);
++ struct i2c_client *client = data->client;
++ u8 outbuf[2];
++ int res = 0;
++
++ if (val == data->raw[channel])
++ return 0;
++
++ outbuf[0] = channel;
++ outbuf[1] = val;
++
++ if (val || data->raw[!channel])
++ res = regulator_enable(data->vcc);
++ if (res)
++ return res;
++
++ res = i2c_master_send(client, outbuf, 2);
++ if (res < 0)
++ return res;
++ else if (res != 2)
++ return -EIO;
++
++ data->raw[channel] = val;
++
++ if (!data->raw[0] && !data->raw[1])
++ regulator_disable(data->vcc);
++
++ return 0;
++}
++
++static int m62332_read_raw(struct iio_dev *indio_dev,
++ struct iio_chan_spec const *chan,
++ int *val,
++ int *val2,
++ long m)
++{
++ struct m62332_data *data = iio_priv(indio_dev);
++
++ switch (m) {
++ case IIO_CHAN_INFO_SCALE:
++ /* Corresponds to Vref / 2^(bits) */
++ *val = data->vref_mv;
++ *val2 = 8;
++ return IIO_VAL_FRACTIONAL_LOG2;
++ case IIO_CHAN_INFO_RAW:
++ *val = data->raw[chan->channel];
++ return IIO_VAL_INT;
++ default:
++ break;
++ }
++ return -EINVAL;
++}
++
++static int m62332_write_raw(struct iio_dev *indio_dev,
++ struct iio_chan_spec const *chan, int val, int val2, long mask)
++{
++ int ret;
++
++ switch (mask) {
++ case IIO_CHAN_INFO_RAW:
++ if (val < 0 || val > 255)
++ return -EINVAL;
++
++ ret = m62332_set_value(indio_dev, val, chan->channel);
++ break;
++ default:
++ ret = -EINVAL;
++ break;
++ }
++
++ return ret;
++}
++
++#ifdef CONFIG_PM_SLEEP
++static int m62332_suspend(struct device *dev)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++ struct iio_dev *indio_dev = i2c_get_clientdata(client);
++ struct m62332_data *data = iio_priv(indio_dev);
++ int ret;
++
++ data->save[0] = data->raw[0];
++ data->save[1] = data->raw[1];
++
++ ret = m62332_set_value(indio_dev, 0, 0);
++ if (ret < 0)
++ return ret;
++
++ return m62332_set_value(indio_dev, 0, 1);
++}
++
++static int m62332_resume(struct device *dev)
++{
++ struct i2c_client *client = to_i2c_client(dev);
++ struct iio_dev *indio_dev = i2c_get_clientdata(client);
++ struct m62332_data *data = iio_priv(indio_dev);
++ int ret;
++
++ ret = m62332_set_value(indio_dev, data->save[0], 0);
++ if (ret < 0)
++ return ret;
++
++ return m62332_set_value(indio_dev, data->save[1], 1);
++}
++
++static SIMPLE_DEV_PM_OPS(m62332_pm_ops, m62332_suspend, m62332_resume);
++#define M62332_PM_OPS (&m62332_pm_ops)
++#else
++#define M62332_PM_OPS NULL
++#endif
++
++static const struct iio_info m62332_info = {
++ .read_raw = m62332_read_raw,
++ .write_raw = m62332_write_raw,
++ .driver_module = THIS_MODULE,
++};
++
++#define M62332_CHANNEL(chan) { \
++ .type = IIO_VOLTAGE, \
++ .indexed = 1, \
++ .output = 1, \
++ .channel = (chan), \
++ .datasheet_name = "CH" #chan, \
++ .info_mask_separate = BIT(IIO_CHAN_INFO_RAW) | \
++ BIT(IIO_CHAN_INFO_SCALE), \
++}
++
++static const struct iio_chan_spec m62332_channels[] = {
++ M62332_CHANNEL(0),
++ M62332_CHANNEL(1)
++};
++
++static int m62332_probe(struct i2c_client *client,
++ const struct i2c_device_id *id)
++{
++ struct m62332_data *data;
++ struct iio_dev *indio_dev;
++
++ indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*data));
++ if (!indio_dev)
++ return -ENOMEM;
++ data = iio_priv(indio_dev);
++ i2c_set_clientdata(client, indio_dev);
++ data->client = client;
++
++ data->vcc = devm_regulator_get(&client->dev, "VCC");
++ if (IS_ERR(data->vcc))
++ return PTR_ERR(data->vcc);
++
++ /* establish that the iio_dev is a child of the i2c device */
++ indio_dev->dev.parent = &client->dev;
++
++ indio_dev->num_channels = 2;
++ indio_dev->channels = m62332_channels;
++ indio_dev->modes = INDIO_DIRECT_MODE;
++ indio_dev->info = &m62332_info;
++
++ data->vref_mv = regulator_get_voltage(data->vcc) / 1000; /* mV */
++
++ iio_map_array_register(indio_dev, client->dev.platform_data);
++
++ return iio_device_register(indio_dev);
++}
++
++static int m62332_remove(struct i2c_client *client)
++{
++ struct iio_dev *indio_dev = i2c_get_clientdata(client);
++
++ iio_device_unregister(indio_dev);
++ iio_map_array_unregister(indio_dev);
++ return 0;
++}
++
++static const struct i2c_device_id m62332_id[] = {
++ { "m62332", },
++ { }
++};
++MODULE_DEVICE_TABLE(i2c, m62332_id);
++
++static struct i2c_driver m62332_driver = {
++ .driver = {
++ .name = "m62332",
++ .pm = M62332_PM_OPS,
++ },
++ .probe = m62332_probe,
++ .remove = m62332_remove,
++ .id_table = m62332_id,
++};
++module_i2c_driver(m62332_driver);
++
++MODULE_AUTHOR("Dmitry Eremin-Solenikov");
++MODULE_DESCRIPTION("M62332 8-bit DAC");
++MODULE_LICENSE("GPL v2");
+--
+1.9.1
+