input: touchscreen: use polling mode in 88pm860x
Subsystems (4)
PATCH 1/6 input: touchscreen: use polling mode in 88pm860x
In reply to a message not in the archiveMeasuring point on touchscreen with IRQ mode can only monitor pen-down event. If finger is moving on touchscreen, it can't be monitored by IRQ pen-down event. So switch to polling mode after pen-down event.
--- drivers/input/touchscreen/88pm860x-ts.c | 82 +++++++++++++++++++++++------- 1 files changed, 63 insertions(+), 19 deletions(-)
drivers/input/touchscreen/88pm860x-ts.c +63 -19
@@ -12,13 +12,25 @@#include <linux/module.h> #include <linux/platform_device.h> #include <linux/i2c.h> +#include <linux/slab.h> #include <linux/input.h> #include <linux/mfd/88pm860x.h> -#include <linux/slab.h> #define MEAS_LEN (8)#define ACCURATE_BIT (12) +/* +* While 32KHz hardware timer is used for scheduler, we always assign HZ +* to 128. It means that 1 tick costs 7.8msec. +*/ +#define MEASURE_INTERVAL_MS (7) + +/* debounce register */ +#define DEBOUNCE (0x0A) + +#define PD_DEBOUNCE_0MSEC (0) +#define PD_DEBOUNCE_MASK (3) +/* touch register */ #define MEAS_EN3 (0x52)
@@ -39,22 +51,27 @@#define MEAS_TSIZ2_EN (1 << 7)struct pm860x_touch { -struct input_dev *idev; -struct i2c_client *i2c; -struct pm860x_chip *chip; -int irq; -int res_x;/* resistor of Xplate */ +struct input_dev *idev; +struct i2c_client *i2c; +struct pm860x_chip *chip; +struct delayed_work poll_work; +struct mutex lock; + +int irq; +int res_x;/* resistor of Xplate */ }; -static irqreturn_t pm860x_touch_handler (int irq,void *data) +static void pm860x_poll_work (struct work_struct *work) { -struct pm860x_touch *touch = data; + struct pm860x_touch *touch = container_of(work, struct pm860x_touch, + poll_work.work);struct pm860x_chip *chip = touch->chip; +int x, y, z1, z2, rt =0 ; +int ret, pen_down, interval;unsigned char buf[MEAS_LEN ]; -int x, y, pen_down; -int z1, z2, rt =0 ; -int ret; +struct timeval start, end; +do_gettimeofday (&start); ret =pm860x_bulk_read (touch->i2c,MEAS_TSIX_1 ,MEAS_LEN , buf);if (ret <0 ) goto out;
@@ -77,30 +94,54 @@ static irqreturn_t pm860x_touch_handler(int irq, void *data)input_report_abs (touch->idev,ABS_PRESSURE , rt);input_report_key (touch->idev,BTN_TOUCH ,1 );dev_dbg (chip->dev,"pen down at [%d, %d].\n" , x, y); + +do_gettimeofday (&end); + interval = (end.tv_sec - start.tv_sec) *1000000 + + (end.tv_usec - start.tv_usec) /1000 ; + interval = (interval <MEASURE_INTERVAL_MS ) + ? (MEASURE_INTERVAL_MS - interval) :0 ; +schedule_delayed_work (&touch->poll_work, +msecs_to_jiffies (interval)); }else {input_report_abs (touch->idev,ABS_PRESSURE ,0 );input_report_key (touch->idev,BTN_TOUCH ,0 );dev_dbg (chip->dev,"pen release\n" ); +mutex_unlock (&touch->lock); }input_sync (touch->idev); out: +return ; +} + +static irqreturn_t pm860x_touch_handler (int irq,void *data) +{ +struct pm860x_touch *touch = data; +int ret; + + ret =pm860x_reg_read (touch->i2c,PM8607_STATUS_1 ); +dev_dbg (touch->chip->dev,"pen status:%d\n" , (ret &PM8607_STATUS_PEN ) + ?1 :0 ); +if ((ret &PM8607_STATUS_PEN ) ==0 ) +return IRQ_HANDLED ; + +mutex_lock (&touch->lock); +pm860x_poll_work (&touch->poll_work.work);return IRQ_HANDLED ; }static int pm860x_touch_open (struct input_dev *dev) {struct pm860x_touch *touch =input_get_drvdata (dev); -int data, ret; +int data; +/* set debounce time with 0ms */ +pm860x_set_bits (touch->i2c,DEBOUNCE ,PD_DEBOUNCE_MASK , +PD_DEBOUNCE_0MSEC ); data =MEAS_PD_EN |MEAS_TSIX_EN |MEAS_TSIY_EN |MEAS_TSIZ1_EN |MEAS_TSIZ2_EN ; - ret =pm860x_set_bits (touch->i2c,MEAS_EN3 , data, data); -if (ret <0 ) - goto out; +pm860x_set_bits (touch->i2c,MEAS_EN3 , data, data);return 0 ; -out: -return ret; }static void pm860x_touch_close (struct input_dev *dev)
@@ -152,16 +193,17 @@ static int __devinit pm860x_touch_probe(struct platform_device *pdev) } touch->idev->name ="88pm860x-touch" ; - touch->idev->phys ="88pm860x/input0" ; + touch->idev->phys ="88pm860x/input1" ; touch->idev->id.bustype =BUS_I2C ; touch->idev->dev.parent = &pdev->dev; touch->idev->open = pm860x_touch_open; touch->idev->close = pm860x_touch_close; touch->chip = chip; touch->i2c = (chip->id ==CHIP_PM8607 ) ? chip->client : chip->companion; - touch->irq = irq + chip->irq_base; + touch->irq = irq; touch->res_x = pdata->res_x;input_set_drvdata (touch->idev, touch); +mutex_init (&touch->lock); ret =request_threaded_irq (touch->irq,NULL , pm860x_touch_handler,IRQF_ONESHOT ,"touch" , touch);
@@ -188,6 +230,7 @@ static int __devinit pm860x_touch_probe(struct platform_device *pdev) }platform_set_drvdata (pdev, touch); +INIT_DELAYED_WORK (&touch->poll_work, pm860x_poll_work);return 0 ; out_rg:free_irq (touch->irq, touch);
@@ -202,6 +245,7 @@ static int __devexit pm860x_touch_remove(struct platform_device *pdev) {struct pm860x_touch *touch =platform_get_drvdata (pdev); +flush_scheduled_work ();input_unregister_device (touch->idev);free_irq (touch->irq, touch);platform_set_drvdata (pdev,NULL );
Signature · 1 line
1.5.6.5
PATCH 3/6 rtc: add 88pm860x rtc
In reply to Haojian ZhuangSupport RTC component in 88PM860x. Also support synchronize time from 88PM860x RTC to another RTC device. It should be implemented in sync callback API.
While 88PM860x RTC is enabled, it can do RTC calibration to gurantee enough power is supplied on VRTC domain of 88PM860x.
--- drivers/mfd/88pm860x-core.c | 30 +++ drivers/rtc/Kconfig | 10 + drivers/rtc/Makefile | 1 + drivers/rtc/rtc-88pm860x.c | 430 ++++++++++++++++++++++++++++++++++++++++++ include/linux/mfd/88pm860x.h | 6 + 5 files changed, 477 insertions(+), 0 deletions(-) create mode 100644 drivers/rtc/rtc-88pm860x.c
drivers/mfd/88pm860x-core.c +30 -0
@@ -57,6 +57,10 @@ static struct resource regulator_resources[] __initdata = { {PM8607_ID_LDO15, PM8607_ID_LDO15, "ldo-15", IORESOURCE_IO,}, }; +static struct resource rtc_resources[]__initdata = { + {PM8607_IRQ_RTC ,PM8607_IRQ_RTC ,"rtc" ,IORESOURCE_IRQ ,}, +}; +static struct resource touch_resources[]__initdata = { {PM8607_IRQ_PEN ,PM8607_IRQ_PEN ,"touch" ,IORESOURCE_IRQ ,}, };
@@ -126,6 +130,10 @@ static struct mfd_cell regulator_devs[] __initdata = { {"88pm860x-regulator", 17,}, }; +static struct mfd_cell rtc_devs[]__initdata = { + {"88pm860x-rtc" ,-1 ,}, +}; +static struct mfd_cell touch_devs[]__initdata = { {"88pm860x-touch" ,-1 ,}, };
@@ -148,6 +156,7 @@ static struct pm860x_led_pdata led_pdata[ARRAY_SIZE(led_devs)];static struct regulator_init_data regulator_pdata[ARRAY_SIZE (regulator_devs)];static struct pm860x_touch_pdata touch_pdata;static struct pm860x_power_pdata power_pdata; +static struct pm860x_rtc_pdata rtc_pdata;struct pm860x_irq_data {int reg;
@@ -585,6 +594,26 @@ out:return ; } +static void __devinit device_rtc_init (struct pm860x_chip *chip, +struct i2c_client *i2c, +struct pm860x_platform_data *pdata) +{ +int ret; + +if ((pdata ==NULL ) || (pdata->rtc ==NULL )) +return ; + +memcpy (&rtc_pdata, pdata->rtc,sizeof (struct pm860x_rtc_pdata )); + rtc_devs[0 ].mfd_data = &rtc_pdata; + rtc_devs[0 ].num_resources =ARRAY_SIZE (rtc_resources); + rtc_devs[0 ].resources = &rtc_resources[0 ]; + ret =mfd_add_devices (chip->dev,0 , &rtc_devs[0 ], +ARRAY_SIZE (rtc_devs), &rtc_resources[0 ], + chip->irq_base); +if (ret <0 ) +dev_err (chip->dev,"Failed to add rtc subdev\n" ); +} +static void __devinit device_touch_init (struct pm860x_chip *chip,struct i2c_client *i2c,struct pm860x_platform_data *pdata)
@@ -713,6 +742,7 @@ static void __devinit device_8607_init(struct pm860x_chip *chip, goto out;device_regulator_init (chip, i2c, pdata); +device_rtc_init (chip, i2c, pdata);device_onkey_init (chip, i2c, pdata);device_touch_init (chip, i2c, pdata);device_power_init (chip, i2c, pdata);
drivers/rtc/Kconfig +10 -0
@@ -128,6 +128,16 @@ comment "I2C RTC drivers" if I2C +config RTC_DRV_88PM860X + tristate "Marvell 88PM860x" + depends on RTC_CLASS && I2C && MFD_88PM860X + help + If you say yes here you get support for RTC function in Marvell + 88PM860x chips. + + This driver can also be built as a module. If so, the module + will be called rtc-88pm860x. + config RTC_DRV_DS1307 tristate "Dallas/Maxim DS1307/37/38/39/40, ST M41T00, EPSON RX-8025" help
drivers/rtc/Makefile +1 -0
@@ -15,6 +15,7 @@ rtc-core-$(CONFIG_RTC_INTF_SYSFS) += rtc-sysfs.o # Keep the list ordered. +obj-$(CONFIG_RTC_DRV_88PM860X) += rtc-88pm860x.o obj-$(CONFIG_RTC_DRV_AB3100) += rtc-ab3100.o obj-$(CONFIG_RTC_DRV_AB8500) += rtc-ab8500.o obj-$(CONFIG_RTC_DRV_AT32AP700X)+= rtc-at32ap700x.o
drivers/rtc/rtc-88pm860x.c new file +430 -0
430 lines not on this page · raw message
include/linux/mfd/88pm860x.h +6 -0
@@ -330,6 +330,11 @@ struct pm860x_led_pdata {unsigned long flags; }; +struct pm860x_rtc_pdata { +int (*sync)(unsigned int ticks); +int vrtc; +}; +struct pm860x_touch_pdata {int gpadc_prebias;int slot_cycle;
@@ -349,6 +354,7 @@ struct pm860x_power_pdata {struct pm860x_platform_data {struct pm860x_backlight_pdata *backlight;struct pm860x_led_pdata *led; +struct pm860x_rtc_pdata *rtc;struct pm860x_touch_pdata *touch;struct pm860x_power_pdata *power;struct regulator_init_data *regulator;
Signature · 1 line
1.5.6.5
PATCH 4/6 input: set the long press detection in 88pm860x onkey
Move the long-press detection from onkey handler to probe function. Avoid unnecessary I2C operation in onkey handler.
--- drivers/input/misc/88pm860x_onkey.c | 6 +++--- 1 files changed, 3 insertions(+), 3 deletions(-)
drivers/input/misc/88pm860x_onkey.c +3 -3
@@ -50,9 +50,6 @@ static irqreturn_t pm860x_onkey_handler(int irq, void *data) ret &=ONKEY_STATUS ;input_report_key (info->idev,KEY_POWER , ret);input_sync (info->idev); - -/* Enable 8-second long onkey detection */ -pm860x_set_bits (info->i2c,PM8607_WAKEUP ,3 ,LONG_ONKEY_EN );return IRQ_HANDLED ; }
@@ -105,6 +102,9 @@ static int __devinit pm860x_onkey_probe(struct platform_device *pdev) }platform_set_drvdata (pdev, info); + +/* Enable 8-second long onkey detection */ +pm860x_set_bits (info->i2c,PM8607_WAKEUP ,3 ,LONG_ONKEY_EN );return 0 ; out_irq:
Signature · 1 line
1.5.6.5
PATCH 5/6 w1: add DS278x slave driver
Append DS278x slave driver.
--- drivers/w1/slaves/Kconfig | 13 +++ drivers/w1/slaves/Makefile | 1 + drivers/w1/slaves/w1_ds278x.c | 184 +++++++++++++++++++++++++++++++++++++++++ drivers/w1/w1_family.h | 3 + 4 files changed, 201 insertions(+), 0 deletions(-) create mode 100644 drivers/w1/slaves/w1_ds278x.c
drivers/w1/slaves/Kconfig +13 -0
@@ -61,6 +61,19 @@ config W1_SLAVE_DS2760 If you are unsure, say N. +config W1_SLAVE_DS278x + tristate "Dallas 278x battery monitor chip" + depends on W1 + help + If you enable this you will have the DS278x battery monitor + chip support. + + The battery monitor chip is used in many batteries/devices + as the one who is responsible for charging/discharging/monitoring + Li+ batteries. + + If you are unsure, say N. + config W1_SLAVE_BQ27000 tristate "BQ27000 slave support" depends on W1
drivers/w1/slaves/Makefile +1 -0
@@ -8,4 +8,5 @@ obj-$(CONFIG_W1_SLAVE_DS2423) += w1_ds2423.o obj-$(CONFIG_W1_SLAVE_DS2431) += w1_ds2431.o obj-$(CONFIG_W1_SLAVE_DS2433) += w1_ds2433.o obj-$(CONFIG_W1_SLAVE_DS2760) += w1_ds2760.o +obj-$(CONFIG_W1_SLAVE_DS278x) += w1_ds278x.o obj-$(CONFIG_W1_SLAVE_BQ27000) += w1_bq27000.o
drivers/w1/slaves/w1_ds278x.c new file +184 -0
184 lines not on this page · raw message
drivers/w1/w1_family.h +3 -0
@@ -36,6 +36,9 @@#define W1_THERM_DS18B20 0x28#define W1_EEPROM_DS2431 0x2D#define W1_FAMILY_DS2760 0x30 +#define W1_BATTMON_DS2780 0x32 +#define W1_BATTMON_DS2781 0x3D +#define W1_BATTMON_DS2783 0x34#define MAXNAMELEN 32
Signature · 1 line
1.5.6.5
PATCH 6/6 mfd: pxa-w1: MFD driver for PXA 1wire control + DS1WM chip
This driver provides registers and IRQ of PXA3xx chips to the ds1wm driver.
--- drivers/mfd/Kconfig | 7 ++ drivers/mfd/Makefile | 1 + drivers/mfd/pxa-w1.c | 149 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 157 insertions(+), 0 deletions(-) create mode 100644 drivers/mfd/pxa-w1.c
drivers/mfd/Kconfig +7 -0
@@ -34,6 +34,13 @@ config MFD_88PM860X select individual components like voltage regulators, RTC and battery-charger under the corresponding menus. +config MFD_PXA_DS1WM + tristate "Support DS1WM chip on Marvell silicons" + select MFD_CORE + help + This core driver provides register access for PXA_DS1WM. + Actual functionality is handled by the ds1wm drivers. + config MFD_SM501 tristate "Support for Silicon Motion SM501" ---help---
drivers/mfd/Makefile +1 -0
@@ -4,6 +4,7 @@ 88pm860x-objs := 88pm860x-core.o 88pm860x-i2c.o obj-$(CONFIG_MFD_88PM860X) += 88pm860x.o +obj-$(CONFIG_MFD_PXA_DS1WM) += pxa-w1.o obj-$(CONFIG_MFD_SM501) += sm501.o obj-$(CONFIG_MFD_ASIC3) += asic3.o tmio_core.o obj-$(CONFIG_MFD_SH_MOBILE_SDHI) += sh_mobile_sdhi.o
drivers/mfd/pxa-w1.c new file +149 -0
149 lines not on this page · raw message
Signature · 1 line
1.5.6.5
PATCH 2/6 input: touchscreen: move initialization in 88pm860x
In reply to Haojian ZhuangMove the GPADC initialization code from mfd driver to touch driver.
--- drivers/input/touchscreen/88pm860x-ts.c | 44 +++++++++++++++++++++----- drivers/mfd/88pm860x-core.c | 51 ------------------------------- 2 files changed, 35 insertions(+), 60 deletions(-)
drivers/input/touchscreen/88pm860x-ts.c +35 -9
@@ -14,6 +14,7 @@#include <linux/i2c.h> #include <linux/slab.h> #include <linux/input.h> +#include <linux/mfd/core.h> #include <linux/mfd/88pm860x.h> #define MEAS_LEN (8)
@@ -154,11 +155,40 @@ static void pm860x_touch_close(struct input_dev *dev)pm860x_set_bits (touch->i2c,MEAS_EN3 , data,0 ); } +static void __devinit pm860x_gpadc_init (struct i2c_client *i2c, +struct pm860x_touch_pdata *pdata) +{ +int data; + +/* set GPADC MISC1 register */ + data =0 ; + data |= (pdata->gpadc_prebias <<1 ) &PM8607_GPADC_PREBIAS_MASK ; + data |= (pdata->slot_cycle <<3 ) &PM8607_GPADC_SLOT_CYCLE_MASK ; + data |= (pdata->off_scale <<5 ) &PM8607_GPADC_OFF_SCALE_MASK ; + data |= (pdata->sw_cal <<7 ) &PM8607_GPADC_SW_CAL_MASK ; +if (data) +pm860x_reg_write (i2c,PM8607_GPADC_MISC1 , data); + +/* set tsi prebias time */ +if (pdata->tsi_prebias) { + data = pdata->tsi_prebias; +pm860x_reg_write (i2c,PM8607_TSI_PREBIAS , data); + } + +/* set prebias & prechg time of pen detect */ + data =0 ; + data |= pdata->pen_prebias &PM8607_PD_PREBIAS_MASK ; + data |= (pdata->pen_prechg <<5 ) &PM8607_PD_PRECHG_MASK ; +if (data) +pm860x_reg_write (i2c,PM8607_PD_PREBIAS , data); + +pm860x_set_bits (i2c,PM8607_GPADC_MISC1 , +PM8607_GPADC_EN ,PM8607_GPADC_EN ); +} +static int __devinit pm860x_touch_probe (struct platform_device *pdev) {struct pm860x_chip *chip =dev_get_drvdata (pdev->dev.parent); -struct pm860x_platform_data *pm860x_pdata = \ - pdev->dev.parent->platform_data;struct pm860x_touch_pdata *pdata =NULL ;struct pm860x_touch *touch;int irq, ret;
@@ -169,13 +199,8 @@ static int __devinit pm860x_touch_probe(struct platform_device *pdev)return -EINVAL ; } -if (!pm860x_pdata) { -dev_err (&pdev->dev,"platform data is missing\n" ); -return -EINVAL ; - } - - pdata = pm860x_pdata->touch; -if (!pdata) { + pdata =mfd_get_data (pdev); +if (pdata ==NULL ) {dev_err (&pdev->dev,"touchscreen data is missing\n" );return -EINVAL ; }
@@ -229,6 +254,7 @@ static int __devinit pm860x_touch_probe(struct platform_device *pdev) goto out_rg; } +pm860x_gpadc_init (touch->i2c, pdata);platform_set_drvdata (pdev, touch);INIT_DELAYED_WORK (&touch->poll_work, pm860x_poll_work);return 0 ;
drivers/mfd/88pm860x-core.c +0 -51
63 lines not on this page · raw message
Signature · 1 line
1.5.6.5