From patchwork Thu Aug 23 10:50:35 2012 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Patil, Rachna" X-Patchwork-Id: 1366621 Return-Path: X-Original-To: patchwork-linux-input@patchwork.kernel.org Delivered-To: patchwork-process-083081@patchwork2.kernel.org Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by patchwork2.kernel.org (Postfix) with ESMTP id 7E0B1E012A for ; Thu, 23 Aug 2012 11:07:18 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1758351Ab2HWLHJ (ORCPT ); Thu, 23 Aug 2012 07:07:09 -0400 Received: from bear.ext.ti.com ([192.94.94.41]:54752 "EHLO bear.ext.ti.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933998Ab2HWLG6 (ORCPT ); Thu, 23 Aug 2012 07:06:58 -0400 Received: from dbdp20.itg.ti.com ([172.24.170.38]) by bear.ext.ti.com (8.13.7/8.13.7) with ESMTP id q7NB6iUO015562; Thu, 23 Aug 2012 06:06:45 -0500 Received: from DBDE70.ent.ti.com (localhost [127.0.0.1]) by dbdp20.itg.ti.com (8.13.8/8.13.8) with ESMTP id q7NB6iVf010612; Thu, 23 Aug 2012 16:36:44 +0530 (IST) Received: from dbdp32.itg.ti.com (172.24.170.251) by dbde70.ent.ti.com (172.24.170.148) with Microsoft SMTP Server id 14.1.323.3; Thu, 23 Aug 2012 16:36:43 +0530 Received: from ucmsshproxy.india.ext.ti.com (dbdp20.itg.ti.com [172.24.170.38]) by dbdp32.itg.ti.com (8.13.8/8.13.8) with SMTP id q7NB6hHo020427; Thu, 23 Aug 2012 16:36:43 +0530 Received: from symphony.india.ext.ti.com (unknown [192.168.247.13]) by ucmsshproxy.india.ext.ti.com (Postfix) with ESMTP id A5B5F158002; Thu, 23 Aug 2012 16:36:43 +0530 (IST) Received: from linux-psp-server.india.ext.ti.com (linux-psp-server [192.168.247.76]) by symphony.india.ext.ti.com (8.11.7p1+Sun/8.11.7) with ESMTP id q7NB6hI03485; Thu, 23 Aug 2012 16:36:43 +0530 (IST) From: "Patil, Rachna" To: , , CC: Dmitry Torokhov , Dmitry Torokhov , Jonathan Cameron , Samuel Ortiz , "Patil, Rachna" Subject: [PATCH 5/5] MFD: ti_tscadc: Add check on number of i/p channels Date: Thu, 23 Aug 2012 16:20:35 +0530 Message-ID: <1345719035-22871-1-git-send-email-rachna@ti.com> X-Mailer: git-send-email 1.7.1 MIME-Version: 1.0 Sender: linux-input-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-input@vger.kernel.org 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 --- 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(-) diff --git a/drivers/iio/adc/ti_adc.c b/drivers/iio/adc/ti_adc.c index a476859..48c5d63 100644 --- a/drivers/iio/adc/ti_adc.c +++ b/drivers/iio/adc/ti_adc.c @@ -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: diff --git a/drivers/input/touchscreen/ti_tsc.c b/drivers/input/touchscreen/ti_tsc.c index cda3b79..26b2a15 100644 --- a/drivers/input/touchscreen/ti_tsc.c +++ b/drivers/input/touchscreen/ti_tsc.c @@ -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: diff --git a/drivers/mfd/ti_tscadc.c b/drivers/mfd/ti_tscadc.c index bf2d488..bac502b 100644 --- a/drivers/mfd/ti_tscadc.c +++ b/drivers/mfd/ti_tscadc.c @@ -22,6 +22,8 @@ #include #include #include +#include +#include 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: