Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in
Toggle navigation
L
linux-davinci
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Redmine
Redmine
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Operations
Operations
Metrics
Environments
Analytics
Analytics
CI / CD
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
linux
linux-davinci
Commits
636e7cf4
Commit
636e7cf4
authored
Mar 20, 2006
by
Tony Lindgren
Browse files
Options
Browse Files
Download
Plain Diff
Merge source.mvista.com:/home/git/linux-omap-2.6
parents
8a024690
73a8a0d8
Changes
1
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
116 additions
and
27 deletions
+116
-27
drivers/input/touchscreen/ads7846.c
drivers/input/touchscreen/ads7846.c
+116
-27
No files found.
drivers/input/touchscreen/ads7846.c
View file @
636e7cf4
...
...
@@ -2,6 +2,7 @@
* ADS7846 based touchscreen and sensor driver
*
* Copyright (c) 2005 David Brownell
* Copyright (c) 2006 Imre Deak <imre.deak@nokia.com>
*
* Using code from:
* - corgi_ts.c
...
...
@@ -33,17 +34,26 @@
/*
* This code has been lightly tested on an ads7846.
* This code has been heavily tested on a Nokia 770, and lightly
* tested on an other ads7846 device.
* Support for ads7843 and ads7845 has only been stubbed in.
*
* Not yet done: investigate the values reported. Are x/y/pressure
* event values sane enough for X11? How accurate are the temperature
* and voltage readings? (System-specific calibration should support
* Not yet done: How accurate are the temperature and voltage
* readings? (System-specific calibration should support
* accuracy of 0.3 degrees C; otherwise it's 2.0 degrees.)
*
* IRQ handling needs a workaround because of a shortcoming in handling
* edge triggered IRQs on some platforms like the OMAP1/2. These
* platforms don't handle the ARM lazy IRQ disabling properly, thus we
* have to maintain our own SW IRQ disabled status. This should be
* removed as soon as the affected platforms' IRQ handling is fixed.
*
* app note sbaa036 talks in more detail about accurate sampling...
* that ought to help in situations like LCDs inducing noise (which
* can also be helped by using synch signals) and more generally.
* This driver tries to utilize the measures described in the app
* note. The strength of filtering can be set in the board-* specific
* files.
*/
#define TS_POLL_PERIOD msecs_to_jiffies(10)
...
...
@@ -90,6 +100,7 @@ struct ads7846 {
unsigned
pending
:
1
;
/* P: lock */
// FIXME remove "irq_disabled"
unsigned
irq_disabled
:
1
;
/* P: lock */
unsigned
disabled
:
1
;
};
/* leave chip selected when we're done, for quicker re-select? */
...
...
@@ -160,6 +171,9 @@ struct ser_req {
struct
spi_transfer
xfer
[
6
];
};
static
void
ads7846_enable
(
struct
ads7846
*
ts
);
static
void
ads7846_disable
(
struct
ads7846
*
ts
);
static
int
ads7846_read12_ser
(
struct
device
*
dev
,
unsigned
command
)
{
struct
spi_device
*
spi
=
to_spi_device
(
dev
);
...
...
@@ -256,6 +270,38 @@ static ssize_t ads7846_pen_down_show(struct device *dev,
static
DEVICE_ATTR
(
pen_down
,
S_IRUGO
,
ads7846_pen_down_show
,
NULL
);
static
ssize_t
ads7846_disable_show
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
char
*
buf
)
{
struct
ads7846
*
ts
=
dev_get_drvdata
(
dev
);
return
sprintf
(
buf
,
"%u
\n
"
,
ts
->
disabled
);
}
static
ssize_t
ads7846_disable_store
(
struct
device
*
dev
,
struct
device_attribute
*
attr
,
const
char
*
buf
,
size_t
count
)
{
struct
ads7846
*
ts
=
dev_get_drvdata
(
dev
);
unsigned
long
flags
;
char
*
endp
;
int
i
;
i
=
simple_strtoul
(
buf
,
&
endp
,
10
);
spin_lock_irqsave
(
&
ts
->
lock
,
flags
);
if
(
i
)
ads7846_disable
(
ts
);
else
ads7846_enable
(
ts
);
spin_unlock_irqrestore
(
&
ts
->
lock
,
flags
);
return
count
;
}
static
DEVICE_ATTR
(
disable
,
0664
,
ads7846_disable_show
,
ads7846_disable_store
);
/*--------------------------------------------------------------------------*/
/*
...
...
@@ -394,12 +440,9 @@ static irqreturn_t ads7846_irq(int irq, void *handle, struct pt_regs *regs)
{
struct
ads7846
*
ts
=
handle
;
unsigned
long
flags
;
int
r
=
IRQ_HANDLED
;
spin_lock_irqsave
(
&
ts
->
lock
,
flags
);
if
(
ts
->
irq_disabled
)
r
=
IRQ_HANDLED
;
else
{
if
(
likely
(
!
ts
->
irq_disabled
&&
!
ts
->
disabled
))
{
if
(
!
ts
->
irq_disabled
)
{
ts
->
irq_disabled
=
1
;
/* The following has at the moment no effect whatsoever
...
...
@@ -413,20 +456,17 @@ static irqreturn_t ads7846_irq(int irq, void *handle, struct pt_regs *regs)
}
}
spin_unlock_irqrestore
(
&
ts
->
lock
,
flags
);
return
r
;
return
IRQ_HANDLED
;
}
/*--------------------------------------------------------------------------*/
static
int
ads7846_suspend
(
struct
spi_device
*
spi
,
pm_message_t
message
)
/* Must be called with ts->lock held */
static
void
ads7846_disable
(
struct
ads7846
*
ts
)
{
struct
ads7846
*
ts
=
dev_get_drvdata
(
&
spi
->
dev
);
unsigned
long
flags
;
spin_lock_irqsave
(
&
ts
->
lock
,
flags
);
spi
->
dev
.
power
.
power_state
=
message
;
if
(
ts
->
disabled
)
return
;
/* are we waiting for IRQ, or polling? */
if
(
!
ts
->
pendown
)
{
...
...
@@ -435,6 +475,8 @@ ads7846_suspend(struct spi_device *spi, pm_message_t message)
disable_irq
(
ts
->
spi
->
irq
);
}
}
else
{
unsigned
long
flags
;
/* polling; force a final SPI completion;
* that will clean things up neatly
*/
...
...
@@ -452,17 +494,48 @@ ads7846_suspend(struct spi_device *spi, pm_message_t message)
* leave it that way after every request
*/
ts
->
disabled
=
1
;
}
/* Must be called with ts->lock held */
static
void
ads7846_enable
(
struct
ads7846
*
ts
)
{
if
(
!
ts
->
disabled
)
return
;
ts
->
disabled
=
0
;
ts
->
irq_disabled
=
0
;
enable_irq
(
ts
->
spi
->
irq
);
}
static
int
ads7846_suspend
(
struct
spi_device
*
spi
,
pm_message_t
message
)
{
struct
ads7846
*
ts
=
dev_get_drvdata
(
&
spi
->
dev
);
unsigned
long
flags
;
spin_lock_irqsave
(
&
ts
->
lock
,
flags
);
spi
->
dev
.
power
.
power_state
=
message
;
ads7846_disable
(
ts
);
spin_unlock_irqrestore
(
&
ts
->
lock
,
flags
);
return
0
;
}
static
int
ads7846_resume
(
struct
spi_device
*
spi
)
{
struct
ads7846
*
ts
=
dev_get_drvdata
(
&
spi
->
dev
);
unsigned
long
flags
;
spin_lock_irqsave
(
&
ts
->
lock
,
flags
);
ts
->
irq_disabled
=
0
;
enable_irq
(
ts
->
spi
->
irq
);
spi
->
dev
.
power
.
power_state
=
PMSG_ON
;
ads7846_enable
(
ts
);
spin_unlock_irqrestore
(
&
ts
->
lock
,
flags
);
return
0
;
}
...
...
@@ -515,6 +588,8 @@ static int __devinit ads7846_probe(struct spi_device *spi)
ts
->
timer
.
data
=
(
unsigned
long
)
ts
;
ts
->
timer
.
function
=
ads7846_timer
;
spin_lock_init
(
&
ts
->
lock
);
ts
->
model
=
pdata
->
model
?
:
7846
;
ts
->
vref_delay_usecs
=
pdata
->
vref_delay_usecs
?
:
100
;
ts
->
x_plate_ohms
=
pdata
->
x_plate_ohms
?
:
400
;
...
...
@@ -665,13 +740,25 @@ static int __devinit ads7846_probe(struct spi_device *spi)
device_create_file
(
&
spi
->
dev
,
&
dev_attr_pen_down
);
device_create_file
(
&
spi
->
dev
,
&
dev_attr_disable
);
err
=
input_register_device
(
input_dev
);
if
(
err
)
goto
err_
free_irq
;
goto
err_
remove_attr
;
return
0
;
err_free_irq:
err_remove_attr:
device_remove_file
(
&
spi
->
dev
,
&
dev_attr_disable
);
device_remove_file
(
&
spi
->
dev
,
&
dev_attr_pen_down
);
if
(
ts
->
model
==
7846
)
{
device_remove_file
(
&
spi
->
dev
,
&
dev_attr_temp1
);
device_remove_file
(
&
spi
->
dev
,
&
dev_attr_temp0
);
}
if
(
ts
->
model
!=
7845
)
device_remove_file
(
&
spi
->
dev
,
&
dev_attr_vbatt
);
device_remove_file
(
&
spi
->
dev
,
&
dev_attr_vaux
);
free_irq
(
spi
->
irq
,
ts
);
err_free_mem:
input_free_device
(
input_dev
);
...
...
@@ -683,22 +770,24 @@ static int __devexit ads7846_remove(struct spi_device *spi)
{
struct
ads7846
*
ts
=
dev_get_drvdata
(
&
spi
->
dev
);
input_unregister_device
(
ts
->
input
);
ads7846_suspend
(
spi
,
PMSG_SUSPEND
);
free_irq
(
ts
->
spi
->
irq
,
ts
);
if
(
ts
->
irq_disabled
)
enable_irq
(
ts
->
spi
->
irq
);
device_remove_file
(
&
spi
->
dev
,
&
dev_attr_disable
);
device_remove_file
(
&
spi
->
dev
,
&
dev_attr_pen_down
);
if
(
ts
->
model
==
7846
)
{
device_remove_file
(
&
spi
->
dev
,
&
dev_attr_temp0
);
device_remove_file
(
&
spi
->
dev
,
&
dev_attr_temp1
);
device_remove_file
(
&
spi
->
dev
,
&
dev_attr_temp0
);
}
if
(
ts
->
model
!=
7845
)
device_remove_file
(
&
spi
->
dev
,
&
dev_attr_vbatt
);
device_remove_file
(
&
spi
->
dev
,
&
dev_attr_vaux
);
input_unregister_device
(
ts
->
input
);
free_irq
(
ts
->
spi
->
irq
,
ts
);
if
(
ts
->
irq_disabled
)
enable_irq
(
ts
->
spi
->
irq
);
kfree
(
ts
);
dev_dbg
(
&
spi
->
dev
,
"unregistered touchscreen
\n
"
);
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment