From: Liang, Dan <hidden> Date: 2008-07-15 04:53:03
Sorry, my mail server has some wrong format setting so the previous
[PATCH 1/2] may be inserted with newline.
Now I resend the [PATCH 1/2].
Signed-off-by: Justin Waters <redacted>
Signed-off-by: Dan Liang <dan.liang <at> atmel.com>
---
drivers/input/touchscreen/Kconfig | 13 ++
drivers/input/touchscreen/Makefile | 1 +
drivers/input/touchscreen/atmel_tsadcc.c | 267
++++++++++++++++++++++++++++++
include/linux/atmel_tsadcc.h | 76 +++++++++
4 files changed, 357 insertions(+), 0 deletions(-)
create mode 100644 drivers/input/touchscreen/atmel_tsadcc.c
create mode 100644 include/linux/atmel_tsadcc.h
diff --git a/drivers/input/touchscreen/Kconfig
b/drivers/input/touchscreen/Kconfig
index 4085791..27eb619 100644
@@ -0,0 +1,267 @@+/*+*AtmelTouchScreenDriver+*+*Copyright(c)2008ATMEL+*Copyright(c)2008DanLiang+*+*BasedontouchscreencodefromAtmelCorporation.+*+*Thisprogramisfreesoftware;youcanredistributeitand/ormodify+*itunderthetermsoftheGNUGeneralPublicLicenseversion2as+*publishedbytheFreeSoftwareFoundation.+*/+#include<linux/init.h>+#include<linux/err.h>+#include<linux/kernel.h>+#include<linux/module.h>+#include<linux/input.h>+#include<linux/slab.h>+#include<linux/interrupt.h>+#include<linux/clk.h>+#include<linux/platform_device.h>+#include<linux/io.h>+#include<linux/atmel_tsadcc.h>++#define ADC_CLOCK 1000000++structatmel_tsadcc{+structinput_dev*input;+charphys[32];+structclk*clk;+intirq;+};++staticvoid__iomem*tsc_base;++#define atmel_tsadcc_read(reg) __raw_readl(tsc_base + (reg))+#define atmel_tsadcc_write(reg, val) __raw_writel((val), tsc_base + (reg))++staticirqreturn_tatmel_tsadcc_interrupt(intirq,void*dev)+{+structinput_dev*input_dev=((structatmel_tsadcc*)dev)->input;++unsignedintabsx;+unsignedintabsy;+unsignedintstatus;+unsignedintreg;++status=atmel_tsadcc_read(ATMEL_TSADCC_SR);+status&=atmel_tsadcc_read(ATMEL_TSADCC_IMR);++/* Contact lost */+if(status&ATMEL_TSADCC_NOCNT){+reg=atmel_tsadcc_read(ATMEL_TSADCC_MR)|ATMEL_TSADCC_PENDBC;++atmel_tsadcc_write(ATMEL_TSADCC_MR,reg);+atmel_tsadcc_write(ATMEL_TSADCC_TRGR,ATMEL_TSADCC_TRGMOD_NONE);+atmel_tsadcc_write(ATMEL_TSADCC_IDR,ATMEL_TSADCC_EOC(3)|ATMEL_TSADCC_NOCNT);+atmel_tsadcc_write(ATMEL_TSADCC_IER,ATMEL_TSADCC_PENCNT);++input_report_key(input_dev,BTN_TOUCH,0);+input_report_abs(input_dev,ABS_PRESSURE,0);+input_sync(input_dev);+}+/* Pen detected */+elseif(status&ATMEL_TSADCC_PENCNT){+reg=atmel_tsadcc_read(ATMEL_TSADCC_MR);+reg&=~ATMEL_TSADCC_PENDBC;++atmel_tsadcc_write(ATMEL_TSADCC_IDR,ATMEL_TSADCC_PENCNT);+atmel_tsadcc_write(ATMEL_TSADCC_MR,reg);+atmel_tsadcc_write(ATMEL_TSADCC_IER,ATMEL_TSADCC_EOC(3)|ATMEL_TSADCC_NOCNT);+atmel_tsadcc_write(ATMEL_TSADCC_TRGR,ATMEL_TSADCC_TRGMOD_PERIOD|(0x0FFF<<16));+}+/* Conversion finished */+elseif(status&ATMEL_TSADCC_EOC(3)){+absx=atmel_tsadcc_read(ATMEL_TSADCC_CDR3)<<10;+absx/=atmel_tsadcc_read(ATMEL_TSADCC_CDR2);++absy=atmel_tsadcc_read(ATMEL_TSADCC_CDR1)<<10;+absy/=atmel_tsadcc_read(ATMEL_TSADCC_CDR0);++input_report_abs(input_dev,ABS_X,absx);+input_report_abs(input_dev,ABS_Y,absy);+input_report_key(input_dev,BTN_TOUCH,1);+input_report_abs(input_dev,ABS_PRESSURE,7500);+input_sync(input_dev);+}+returnIRQ_HANDLED;+}++/*+*Thefunctionsforinserting/removingusasamodule.+*/++staticint__devinitatmel_tsadcc_probe(structplatform_device*pdev)+{+structatmel_tsadcc*ts_dev;+structinput_dev*input_dev;+structresource*res;+interr=0;+unsignedintprsc;+unsignedintreg;++res=platform_get_resource(pdev,IORESOURCE_MEM,0);+if(!res){+dev_err(&pdev->dev,"no mmio resource defined.\n");+return-ENXIO;+}++/* Allocate memory for device */+ts_dev=kzalloc(sizeof(structatmel_tsadcc),GFP_KERNEL);+if(!ts_dev){+dev_err(&pdev->dev,"failed to allocate memory.\n");+return-ENOMEM;+}+platform_set_drvdata(pdev,ts_dev);++input_dev=input_allocate_device();+if(!input_dev){+dev_err(&pdev->dev,"failed to allocate input device.\n");+err=-EBUSY;+gotoerr_free_mem;+}++ts_dev->irq=platform_get_irq(pdev,0);+if(ts_dev->irq<0){+dev_err(&pdev->dev,"no irq ID is designated.\n");+err=-ENODEV;+gotoerr_free_dev;+}++if(!request_mem_region(res->start,res->end-res->start+1,"atmel tsadcc regs")){+dev_err(&pdev->dev,"resources is unavailable.\n");+err=-EBUSY;+gotoerr_free_dev;+}++tsc_base=ioremap(res->start,res->end-res->start+1);+if(!tsc_base){+dev_err(&pdev->dev,"failed to map registers.\n");+err=-ENOMEM;+gotoerr_release_mem;+}++err=request_irq(ts_dev->irq,atmel_tsadcc_interrupt,IRQF_DISABLED,+pdev->dev.driver->name,ts_dev);+if(err){+dev_err(&pdev->dev,"failed to allocate irq.\n");+gotoerr_unmap_regs;+}++ts_dev->clk=clk_get(&pdev->dev,"tsc_clk");+if(IS_ERR(ts_dev->clk)){+dev_err(&pdev->dev,"failed to get ts_clk\n");+err=PTR_ERR(ts_dev->clk);+gotoerr_free_irq;+}++ts_dev->input=input_dev;++snprintf(ts_dev->phys,sizeof(ts_dev->phys),"%s/input0",pdev->dev.bus_id);++input_dev->name="atmel touch screen controller";+input_dev->phys=ts_dev->phys;+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_set_abs_params(input_dev,ABS_X,0,0x3FF,0,0);+input_set_abs_params(input_dev,ABS_Y,0,0x3FF,0,0);+input_set_abs_params(input_dev,ABS_PRESSURE,0,15000,0,0);++/* clk_enable() always returns 0, no need to check it */+clk_enable(ts_dev->clk);++prsc=clk_get_rate(ts_dev->clk);+dev_info(&pdev->dev,"Master clock is set at: %d Hz\n",prsc);++prsc=prsc/ADC_CLOCK/2-1;++reg=ATMEL_TSADCC_TSAMOD_TS_ONLY_MODE|+((0x00<<5)&ATMEL_TSADCC_SLEEP)|/* Normal Mode */+((0x01<<6)&ATMEL_TSADCC_PENDET)|/* Enable Pen Detect */+((prsc<<8)&ATMEL_TSADCC_PRESCAL)|/* PRESCAL */+((0x13<<16)&ATMEL_TSADCC_STARTUP)|/* STARTUP */+((0x0F<<28)&ATMEL_TSADCC_PENDBC);/* PENDBC */++atmel_tsadcc_write(ATMEL_TSADCC_CR,ATMEL_TSADCC_SWRST);+atmel_tsadcc_write(ATMEL_TSADCC_MR,reg);+atmel_tsadcc_write(ATMEL_TSADCC_TRGR,ATMEL_TSADCC_TRGMOD_NONE);+atmel_tsadcc_write(ATMEL_TSADCC_TSR,(0x3<<24)&ATMEL_TSADCC_TSSHTIM);++atmel_tsadcc_read(ATMEL_TSADCC_SR);+atmel_tsadcc_write(ATMEL_TSADCC_IER,ATMEL_TSADCC_PENCNT);++/* All went ok, so register to the input system */+err=input_register_device(input_dev);+if(err)+gotoerr_fail;++return0;++err_fail:+clk_disable(ts_dev->clk);+clk_put(ts_dev->clk);+err_free_irq:+free_irq(ts_dev->irq,ts_dev);+err_unmap_regs:+iounmap(tsc_base);+err_release_mem:+release_mem_region(res->start,res->end-res->start+1);+err_free_dev:+input_free_device(ts_dev->input);+err_free_mem:+kfree(ts_dev);+returnerr;+}++staticint__devexitatmel_tsadcc_remove(structplatform_device*pdev)+{+structatmel_tsadcc*ts_dev=dev_get_drvdata(&pdev->dev);+structresource*res;++disable_irq(ts_dev->irq);+free_irq(ts_dev->irq,ts_dev);++input_unregister_device(ts_dev->input);++res=platform_get_resource(pdev,IORESOURCE_MEM,0);+iounmap(tsc_base);+release_mem_region(res->start,res->end-res->start+1);++clk_disable(ts_dev->clk);+clk_put(ts_dev->clk);++kfree(ts_dev);++return0;+}++staticstructplatform_driveratmel_tsadcc_driver={+.probe=atmel_tsadcc_probe,+.remove=__devexit_p(atmel_tsadcc_remove),+.driver={+.name="atmel_tsadcc",+}+};++int__initatmel_tsadcc_init(void)+{+returnplatform_driver_register(&atmel_tsadcc_driver);+}++void__exitatmel_tsadcc_exit(void)+{+platform_driver_unregister(&atmel_tsadcc_driver);+}++module_init(atmel_tsadcc_init);+module_exit(atmel_tsadcc_exit);+++MODULE_LICENSE("GPL");+MODULE_DESCRIPTION("Atmel TouchScreen Driver");+MODULE_AUTHOR("Dan Liang <dan.liang@atmel.com>");+
Hi Dan,
On Tue, Jul 15, 2008 at 12:06:22PM +0200, Liang, Dan wrote:
Sorry again, the previous [PATCH 1/2] still has some formatting problems.
Now finally I fixed it.
The AT91SAM9RL SoC integrates a Touchscreen Controller which can trigger ADC conversion periodically.
Overall looks good, just a couple of comments:
- The device does not seem to support pressure reading so I will drop
ABS_PRESSURE reporting.
- The header file - is it needed? If there are no other users of this
file expected I will fold it into the driver.
Thanks!
--
Dmitry
From: Liang, Dan <hidden> Date: 2008-07-21 02:13:04
Hi Dmitry,
- The device does not seem to support pressure reading so I will drop
ABS_PRESSURE reporting.
I tried to remove the faked pressure report and tested with tslib. But there is an error message:
"selected device is not a touchscreen I understand". And the touch screen seems not to work properly.
- The header file - is it needed? If there are no other users of this
file expected I will fold it into the driver.
Currently the header file is used only by this touch screen driver although the peripheral can also work as a general ADC. The most common usage will be as a touch screen controller.
Thanks!
--
Dan
On Mon, Jul 21, 2008 at 04:12:35AM +0200, Liang, Dan wrote:
Hi Dmitry,
quoted
- The device does not seem to support pressure reading so I will drop
ABS_PRESSURE reporting.
I tried to remove the faked pressure report and tested with tslib. But there is an error message:
"selected device is not a touchscreen I understand". And the touch screen seems not to work properly.
This is the problem with tslib and I am hoping that someone will find
the time to fix it there.
--
Dmitry
From: Liang, Dan <hidden> Date: 2008-07-21 09:57:39
Dmitry Torokhov wrote:
quoted
Hi Dmitry,
quoted
- The device does not seem to support pressure reading so I will drop
ABS_PRESSURE reporting.
I tried to remove the faked pressure report and tested with tslib. But there is an error message:
"selected device is not a touchscreen I understand". And the touch screen seems not to work properly.
This is the problem with tslib and I am hoping that someone will find
the time to fix it there.
Hi Dmitry,
To make the driver to work properly before someone fixs tslib, I wonder if the ABS_PRESSURE reporting could be kept for the moment. Other driver like "drivers/input/touchscreen/ads7846.c" also fakes the pressure value for ads7843 chip.
And another issue, could you please add the copyright in "drivers/input/touchscreen/atmel_tsadcc.c":
* Copyright (c) 2008 TimeSys Corporation
* Copyright (c) 2008 Justin Waters
Best regards
Dan
Hi Dan,
On Mon, Jul 21, 2008 at 11:55:35AM +0200, Liang, Dan wrote:
Dmitry Torokhov wrote:
quoted
quoted
Hi Dmitry,
quoted
- The device does not seem to support pressure reading so I will drop
ABS_PRESSURE reporting.
I tried to remove the faked pressure report and tested with tslib. But there is an error message:
"selected device is not a touchscreen I understand". And the touch screen seems not to work properly.
This is the problem with tslib and I am hoping that someone will find
the time to fix it there.
Hi Dmitry,
To make the driver to work properly before someone fixs tslib,
I wonder if the ABS_PRESSURE reporting could be kept for the
moment.
Then nobody will ever fix it ;)
Other driver like "drivers/input/touchscreen/ads7846.c" also fakes
the pressure value for ads7843 chip.
I will take patches correcting this.
And another issue, could you please add the copyright in
"drivers/input/touchscreen/atmel_tsadcc.c":
* Copyright (c) 2008 TimeSys Corporation
* Copyright (c) 2008 Justin Waters