@@ -142,37 +142,38 @@ static int __devinit tiadc_probe(struct platform_device *pdev)
return -EINVAL;
}
- idev = iio_device_alloc(sizeof(struct adc_device));
- if (idev == NULL) {
- dev_err(&pdev->dev, "failed to allocate iio device.\n");
- err = -ENOMEM;
- goto err_ret;
- }
- adc_dev = iio_priv(idev);
-
- tscadc_dev->adc = adc_dev;
- adc_dev->mfd_tscadc = tscadc_dev;
- adc_dev->idev = idev;
- adc_dev->adc_channels = board_data->adc_init->adc_channels;
+ if (board_data->adc_init->adc_channels != 0) {
+ idev = iio_device_alloc(sizeof(struct adc_device));
+ if (idev == NULL) {
+ dev_err(&pdev->dev, "failed to allocate iio device.\n");
+ err = -ENOMEM;
+ goto err_ret;
+ }
+ adc_dev = iio_priv(idev);
- idev->dev.parent = &pdev->dev;
- idev->name = dev_name(&pdev->dev);
- idev->modes = INDIO_DIRECT_MODE;
- idev->info = &tiadc_info;
+ tscadc_dev->adc = adc_dev;
+ adc_dev->mfd_tscadc = tscadc_dev;
+ adc_dev->idev = idev;
+ adc_dev->adc_channels = board_data->adc_init->adc_channels;
- adc_step_config(adc_dev);
+ idev->dev.parent = &pdev->dev;
+ idev->name = dev_name(&pdev->dev);
+ idev->modes = INDIO_DIRECT_MODE;
+ idev->info = &tiadc_info;
- err = tiadc_channel_init(idev, adc_dev);
- if (err < 0)
- goto err_fail;
+ adc_step_config(adc_dev);
- err = iio_device_register(idev);
- if (err)
- goto err_free_channels;
+ err = tiadc_channel_init(idev, adc_dev);
+ if (err < 0)
+ goto err_fail;
- dev_info(&pdev->dev, "attached adc driver\n");
- platform_set_drvdata(pdev, idev);
+ err = iio_device_register(idev);
+ if (err)
+ goto err_free_channels;
+ dev_info(&pdev->dev, "attached adc driver\n");
+ platform_set_drvdata(pdev, idev);
+ }
return 0;
err_free_channels:
@@ -271,50 +271,55 @@ static int __devinit tscadc_probe(struct platform_device *pdev)
return -EINVAL;
}
- /* Allocate memory for device */
- ts_dev = kzalloc(sizeof(struct tscadc), GFP_KERNEL);
- input_dev = input_allocate_device();
- if (!ts_dev || !input_dev) {
- dev_err(&pdev->dev, "failed to allocate memory.\n");
- err = -ENOMEM;
- goto err_free_mem;
- }
+ if (board_data->tsc_init->wires != 0) {
+ /* Allocate memory for device */
+ ts_dev = kzalloc(sizeof(struct tscadc), GFP_KERNEL);
+ input_dev = input_allocate_device();
+ if (!ts_dev || !input_dev) {
+ dev_err(&pdev->dev, "failed to allocate memory.\n");
+ err = -ENOMEM;
+ goto err_free_mem;
+ }
- tscadc_dev->tsc = ts_dev;
- ts_dev->mfd_tscadc = tscadc_dev;
- ts_dev->input = input_dev;
- ts_dev->irq = tscadc_dev->irq;
- ts_dev->wires = board_data->tsc_init->wires;
- ts_dev->x_plate_resistance = board_data->tsc_init->x_plate_resistance;
- ts_dev->steps_to_configure = board_data->tsc_init->steps_to_configure;
-
- err = request_irq(ts_dev->irq, tscadc_irq,
- 0, pdev->dev.driver->name, ts_dev);
- if (err) {
- dev_err(&pdev->dev, "failed to allocate irq.\n");
- goto err_free_mem;
- }
+ tscadc_dev->tsc = ts_dev;
+ ts_dev->mfd_tscadc = tscadc_dev;
+ ts_dev->input = input_dev;
+ ts_dev->irq = tscadc_dev->irq;
+ ts_dev->wires = board_data->tsc_init->wires;
+ ts_dev->x_plate_resistance =
+ board_data->tsc_init->x_plate_resistance;
+ ts_dev->steps_to_configure =
+ board_data->tsc_init->steps_to_configure;
+
+ err = request_irq(ts_dev->irq, tscadc_irq,
+ 0, pdev->dev.driver->name, ts_dev);
+ if (err) {
+ dev_err(&pdev->dev, "failed to allocate irq.\n");
+ goto err_free_mem;
+ }
- tscadc_writel(ts_dev, REG_IRQENABLE, IRQENB_FIFO0THRES);
- tscadc_step_config(ts_dev);
- tscadc_writel(ts_dev, REG_FIFO0THR, ts_dev->steps_to_configure);
+ tscadc_writel(ts_dev, REG_IRQENABLE, IRQENB_FIFO0THRES);
+ tscadc_step_config(ts_dev);
+ tscadc_writel(ts_dev, REG_FIFO0THR, ts_dev->steps_to_configure);
- input_dev->name = "ti-tsc";
- input_dev->dev.parent = &pdev->dev;
+ input_dev->name = "ti-tsc";
+ input_dev->dev.parent = &pdev->dev;
- input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
- input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
+ input_dev->evbit[0] = BIT_MASK(EV_KEY) | BIT_MASK(EV_ABS);
+ input_dev->keybit[BIT_WORD(BTN_TOUCH)] = BIT_MASK(BTN_TOUCH);
- input_set_abs_params(input_dev, ABS_X, 0, MAX_12BIT, 0, 0);
- input_set_abs_params(input_dev, ABS_Y, 0, MAX_12BIT, 0, 0);
- input_set_abs_params(input_dev, ABS_PRESSURE, 0, MAX_12BIT, 0, 0);
+ input_set_abs_params(input_dev, ABS_X, 0, MAX_12BIT, 0, 0);
+ input_set_abs_params(input_dev, ABS_Y, 0, MAX_12BIT, 0, 0);
+ input_set_abs_params(input_dev, ABS_PRESSURE, 0, MAX_12BIT,
+ 0, 0);
- /* register to the input system */
- err = input_register_device(input_dev);
- if (err)
- goto err_free_irq;
+ /* register to the input system */
+ err = input_register_device(input_dev);
+ if (err)
+ goto err_free_irq;
- platform_set_drvdata(pdev, ts_dev);
+ platform_set_drvdata(pdev, ts_dev);
+ }
return 0;
err_free_irq:
@@ -22,6 +22,8 @@
#include <linux/mfd/core.h>
#include <linux/pm_runtime.h>
#include <linux/mfd/ti_tscadc.h>
+#include <linux/platform_data/ti_adc.h>
+#include <linux/input/ti_tscadc.h>
static unsigned int tscadc_readl(struct ti_tscadc_dev *tsadc, unsigned int reg)
{
@@ -51,105 +53,119 @@ static int __devinit ti_tscadc_probe(struct platform_device *pdev)
int clk_value, clock_rate;
struct resource *res;
struct clk *clk;
+ int tsc_wires, adc_channels, total_channels;
struct mfd_cell *cell = NULL;
+ struct mfd_tscadc_board *board_data = pdev->dev.platform_data;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- dev_err(&pdev->dev, "no memory resource defined.\n");
+ if (!board_data) {
+ dev_err(&pdev->dev, "Could not find platform data\n");
return -EINVAL;
}
- /* Allocate memory for device */
- tscadc = kzalloc(sizeof(struct ti_tscadc_dev), GFP_KERNEL);
- if (!tscadc) {
- dev_err(&pdev->dev, "failed to allocate memory.\n");
- return -ENOMEM;
- }
-
- res = request_mem_region(res->start, resource_size(res), pdev->name);
- if (!res) {
- dev_err(&pdev->dev, "failed to reserve registers.\n");
- err = -EBUSY;
- goto err_free_mem;
- }
-
- tscadc->tscadc_base = ioremap(res->start, resource_size(res));
- if (!tscadc->tscadc_base) {
- dev_err(&pdev->dev, "failed to map registers.\n");
- err = -ENOMEM;
- goto err_release_mem;
- }
-
- tscadc->irq = platform_get_irq(pdev, 0);
- if (tscadc->irq < 0) {
- dev_err(&pdev->dev, "no irq ID is specified.\n");
- return -ENODEV;
- }
-
- tscadc->dev = &pdev->dev;
-
- pm_runtime_enable(&pdev->dev);
- pm_runtime_get_sync(&pdev->dev);
-
- /*
- * The TSC_ADC_Subsystem has 2 clock domains
- * OCP_CLK and ADC_CLK.
- * The ADC clock is expected to run at target of 3MHz,
- * and expected to capture 12-bit data at a rate of 200 KSPS.
- * The TSC_ADC_SS controller design assumes the OCP clock is
- * at least 6x faster than the ADC clock.
- */
- clk = clk_get(&pdev->dev, "adc_tsc_fck");
- if (IS_ERR(clk)) {
- dev_err(&pdev->dev, "failed to get TSC fck\n");
- err = PTR_ERR(clk);
- goto err_fail;
- }
- clock_rate = clk_get_rate(clk);
- clk_put(clk);
- clk_value = clock_rate / ADC_CLK;
- if (clk_value < MAX_CLK_DIV) {
- dev_err(&pdev->dev, "clock input less than min clock requirement\n");
- err = -EINVAL;
- goto err_fail;
+ tsc_wires = board_data->tsc_init->wires;
+ adc_channels = board_data->adc_init->adc_channels;
+ total_channels = tsc_wires + adc_channels;
+
+ if (total_channels <= 8) {
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "no memory resource defined.\n");
+ return -EINVAL;
+ }
+
+ /* Allocate memory for device */
+ tscadc = kzalloc(sizeof(struct ti_tscadc_dev), GFP_KERNEL);
+ if (!tscadc) {
+ dev_err(&pdev->dev, "failed to allocate memory.\n");
+ return -ENOMEM;
+ }
+
+ res = request_mem_region(res->start, resource_size(res),
+ pdev->name);
+ if (!res) {
+ dev_err(&pdev->dev, "failed to reserve registers.\n");
+ err = -EBUSY;
+ goto err_free_mem;
+ }
+
+ tscadc->tscadc_base = ioremap(res->start, resource_size(res));
+ if (!tscadc->tscadc_base) {
+ dev_err(&pdev->dev, "failed to map registers.\n");
+ err = -ENOMEM;
+ goto err_release_mem;
+ }
+
+ tscadc->irq = platform_get_irq(pdev, 0);
+ if (tscadc->irq < 0) {
+ dev_err(&pdev->dev, "no irq ID is specified.\n");
+ return -ENODEV;
+ }
+
+ tscadc->dev = &pdev->dev;
+
+ pm_runtime_enable(&pdev->dev);
+ pm_runtime_get_sync(&pdev->dev);
+
+ /*
+ * The TSC_ADC_Subsystem has 2 clock domains
+ * OCP_CLK and ADC_CLK.
+ * The ADC clock is expected to run at target of 3MHz,
+ * and expected to capture 12-bit data at a rate of 200 KSPS.
+ * The TSC_ADC_SS controller design assumes the OCP clock is
+ * at least 6x faster than the ADC clock.
+ */
+ clk = clk_get(&pdev->dev, "adc_tsc_fck");
+ if (IS_ERR(clk)) {
+ dev_err(&pdev->dev, "failed to get TSC fck\n");
+ err = PTR_ERR(clk);
+ goto err_fail;
+ }
+ clock_rate = clk_get_rate(clk);
+ clk_put(clk);
+ clk_value = clock_rate / ADC_CLK;
+ if (clk_value < MAX_CLK_DIV) {
+ dev_err(&pdev->dev, "clock input less than min clock requirement\n");
+ err = -EINVAL;
+ goto err_fail;
+ }
+ /* TSCADC_CLKDIV needs to be configured to the value minus 1 */
+ clk_value = clk_value - 1;
+ tscadc_writel(tscadc, REG_CLKDIV, clk_value);
+
+ /* Set the control register bits */
+ ctrl = CNTRLREG_STEPCONFIGWRT |
+ CNTRLREG_TSCENB |
+ CNTRLREG_STEPID |
+ CNTRLREG_4WIRE;
+ tscadc_writel(tscadc, REG_CTRL, ctrl);
+
+ /* Set register bits for Idle Config Mode */
+ tscadc_idle_config(tscadc);
+
+ /* Enable the TSC module enable bit */
+ ctrl = tscadc_readl(tscadc, REG_CTRL);
+ ctrl |= CNTRLREG_TSCSSENB;
+ tscadc_writel(tscadc, REG_CTRL, ctrl);
+
+ /* TSC Cell */
+ cell = &tscadc->cells[TSC_CELL];
+ cell->name = "tsc";
+ cell->platform_data = tscadc;
+ cell->pdata_size = sizeof(*tscadc);
+
+ /* ADC Cell */
+ cell = &tscadc->cells[ADC_CELL];
+ cell->name = "tiadc";
+ cell->platform_data = tscadc;
+ cell->pdata_size = sizeof(*tscadc);
+
+ err = mfd_add_devices(&pdev->dev, pdev->id, tscadc->cells,
+ TSCADC_CELLS, NULL, 0);
+ if (err < 0)
+ goto err_fail;
+
+ platform_set_drvdata(pdev, tscadc);
}
- /* TSCADC_CLKDIV needs to be configured to the value minus 1 */
- clk_value = clk_value - 1;
- tscadc_writel(tscadc, REG_CLKDIV, clk_value);
-
- /* Set the control register bits */
- ctrl = CNTRLREG_STEPCONFIGWRT |
- CNTRLREG_TSCENB |
- CNTRLREG_STEPID |
- CNTRLREG_4WIRE;
- tscadc_writel(tscadc, REG_CTRL, ctrl);
-
- /* Set register bits for Idle Config Mode */
- tscadc_idle_config(tscadc);
-
- /* Enable the TSC module enable bit */
- ctrl = tscadc_readl(tscadc, REG_CTRL);
- ctrl |= CNTRLREG_TSCSSENB;
- tscadc_writel(tscadc, REG_CTRL, ctrl);
-
- /* TSC Cell */
- cell = &tscadc->cells[TSC_CELL];
- cell->name = "tsc";
- cell->platform_data = tscadc;
- cell->pdata_size = sizeof(*tscadc);
-
- /* ADC Cell */
- cell = &tscadc->cells[ADC_CELL];
- cell->name = "tiadc";
- cell->platform_data = tscadc;
- cell->pdata_size = sizeof(*tscadc);
-
- err = mfd_add_devices(&pdev->dev, pdev->id, tscadc->cells,
- TSCADC_CELLS, NULL, 0);
- if (err < 0)
- goto err_fail;
-
- platform_set_drvdata(pdev, tscadc);
return 0;
err_fail:
The controller provides a total of 8 analog input lines, which can be used as: 1. 8 general purpose ADC channels 2. 4 wire TS, with 4 general purpose ADC channels 3. 5 wire TS, with 3 general purpose ADC channels Signed-off-by: Patil, Rachna <rachna@ti.com> --- drivers/iio/adc/ti_adc.c | 51 +++++----- drivers/input/touchscreen/ti_tsc.c | 79 ++++++++------- drivers/mfd/ti_tscadc.c | 202 +++++++++++++++++++----------------- 3 files changed, 177 insertions(+), 155 deletions(-)