Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Support
Keyboard shortcuts
?
Submit feedback
Contribute to GitLab
Sign in / Register
Toggle navigation
L
linux
Project overview
Project overview
Details
Activity
Releases
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Issues
0
Issues
0
List
Boards
Labels
Milestones
Merge Requests
0
Merge Requests
0
Analytics
Analytics
Repository
Value Stream
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Create a new issue
Commits
Issue Boards
Open sidebar
Kirill Smelkov
linux
Commits
28b4c294
Commit
28b4c294
authored
Jan 21, 2014
by
Lee Jones
Browse files
Options
Browse Files
Download
Plain Diff
Merge tag 'ib-iio-input-3.13-1' into for-mfd-next
Immutable branch for IIO and Input
parents
09fd19da
7ca6740c
Changes
4
Hide whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
117 additions
and
34 deletions
+117
-34
drivers/iio/adc/ti_am335x_adc.c
drivers/iio/adc/ti_am335x_adc.c
+49
-19
drivers/input/touchscreen/ti_am335x_tsc.c
drivers/input/touchscreen/ti_am335x_tsc.c
+2
-2
drivers/mfd/ti_am335x_tscadc.c
drivers/mfd/ti_am335x_tscadc.c
+60
-11
include/linux/mfd/ti_am335x_tscadc.h
include/linux/mfd/ti_am335x_tscadc.h
+6
-2
No files found.
drivers/iio/adc/ti_am335x_adc.c
View file @
28b4c294
...
...
@@ -60,6 +60,24 @@ static u32 get_adc_step_mask(struct tiadc_device *adc_dev)
return
step_en
;
}
static
u32
get_adc_chan_step_mask
(
struct
tiadc_device
*
adc_dev
,
struct
iio_chan_spec
const
*
chan
)
{
int
i
;
for
(
i
=
0
;
i
<
ARRAY_SIZE
(
adc_dev
->
channel_step
);
i
++
)
{
if
(
chan
->
channel
==
adc_dev
->
channel_line
[
i
])
{
u32
step
;
step
=
adc_dev
->
channel_step
[
i
];
/* +1 for the charger */
return
1
<<
(
step
+
1
);
}
}
WARN_ON
(
1
);
return
0
;
}
static
u32
get_adc_step_bit
(
struct
tiadc_device
*
adc_dev
,
int
chan
)
{
return
1
<<
adc_dev
->
channel_step
[
chan
];
...
...
@@ -181,7 +199,7 @@ static int tiadc_buffer_postenable(struct iio_dev *indio_dev)
enb
|=
(
get_adc_step_bit
(
adc_dev
,
bit
)
<<
1
);
adc_dev
->
buffer_en_ch_steps
=
enb
;
am335x_tsc_se_set
(
adc_dev
->
mfd_tscadc
,
enb
);
am335x_tsc_se_set
_cache
(
adc_dev
->
mfd_tscadc
,
enb
);
tiadc_writel
(
adc_dev
,
REG_IRQSTATUS
,
IRQENB_FIFO1THRES
|
IRQENB_FIFO1OVRRUN
|
IRQENB_FIFO1UNDRFLW
);
...
...
@@ -199,6 +217,7 @@ static int tiadc_buffer_predisable(struct iio_dev *indio_dev)
tiadc_writel
(
adc_dev
,
REG_IRQCLR
,
(
IRQENB_FIFO1THRES
|
IRQENB_FIFO1OVRRUN
|
IRQENB_FIFO1UNDRFLW
));
am335x_tsc_se_clr
(
adc_dev
->
mfd_tscadc
,
adc_dev
->
buffer_en_ch_steps
);
adc_dev
->
buffer_en_ch_steps
=
0
;
/* Flush FIFO of leftover data in the time it takes to disable adc */
fifo1count
=
tiadc_readl
(
adc_dev
,
REG_FIFO1CNT
);
...
...
@@ -328,34 +347,43 @@ static int tiadc_read_raw(struct iio_dev *indio_dev,
unsigned
int
fifo1count
,
read
,
stepid
;
bool
found
=
false
;
u32
step_en
;
unsigned
long
timeout
=
jiffies
+
usecs_to_jiffies
(
IDLE_TIMEOUT
*
adc_dev
->
channels
);
unsigned
long
timeout
;
if
(
iio_buffer_enabled
(
indio_dev
))
return
-
EBUSY
;
step_en
=
get_adc_step_mask
(
adc_dev
);
am335x_tsc_se_set
(
adc_dev
->
mfd_tscadc
,
step_en
);
step_en
=
get_adc_chan_step_mask
(
adc_dev
,
chan
);
if
(
!
step_en
)
return
-
EINVAL
;
fifo1count
=
tiadc_readl
(
adc_dev
,
REG_FIFO1CNT
);
while
(
fifo1count
--
)
tiadc_readl
(
adc_dev
,
REG_FIFO1
);
am335x_tsc_se_set_once
(
adc_dev
->
mfd_tscadc
,
step_en
);
/* Wait for ADC sequencer to complete sampling */
while
(
tiadc_readl
(
adc_dev
,
REG_ADCFSM
)
&
SEQ_STATUS
)
{
if
(
time_after
(
jiffies
,
timeout
))
timeout
=
jiffies
+
usecs_to_jiffies
(
IDLE_TIMEOUT
*
adc_dev
->
channels
);
/* Wait for Fifo threshold interrupt */
while
(
1
)
{
fifo1count
=
tiadc_readl
(
adc_dev
,
REG_FIFO1CNT
);
if
(
fifo1count
)
break
;
if
(
time_after
(
jiffies
,
timeout
))
{
am335x_tsc_se_adc_done
(
adc_dev
->
mfd_tscadc
);
return
-
EAGAIN
;
}
}
map_val
=
chan
->
channel
+
TOTAL_CHANNELS
;
/*
* When the sub-system is first enabled,
* the sequencer will always start with the
* lowest step (1) and continue until step (16).
* For ex: If we have enabled 4 ADC channels and
* currently use only 1 out of them, the
* sequencer still configures all the 4 steps,
* leading to 3 unwanted data.
* Hence we need to flush out this data.
* We check the complete FIFO. We programmed just one entry but in case
* something went wrong we left empty handed (-EAGAIN previously) and
* then the value apeared somehow in the FIFO we would have two entries.
* Therefore we read every item and keep only the latest version of the
* requested channel.
*/
fifo1count
=
tiadc_readl
(
adc_dev
,
REG_FIFO1CNT
);
for
(
i
=
0
;
i
<
fifo1count
;
i
++
)
{
read
=
tiadc_readl
(
adc_dev
,
REG_FIFO1
);
stepid
=
read
&
FIFOREAD_CHNLID_MASK
;
...
...
@@ -367,6 +395,7 @@ static int tiadc_read_raw(struct iio_dev *indio_dev,
*
val
=
(
u16
)
read
;
}
}
am335x_tsc_se_adc_done
(
adc_dev
->
mfd_tscadc
);
if
(
found
==
false
)
return
-
EBUSY
;
...
...
@@ -494,7 +523,8 @@ static int tiadc_resume(struct device *dev)
tiadc_writel
(
adc_dev
,
REG_CTRL
,
restore
);
tiadc_step_config
(
indio_dev
);
am335x_tsc_se_set_cache
(
adc_dev
->
mfd_tscadc
,
adc_dev
->
buffer_en_ch_steps
);
return
0
;
}
...
...
drivers/input/touchscreen/ti_am335x_tsc.c
View file @
28b4c294
...
...
@@ -198,7 +198,7 @@ static void titsc_step_config(struct titsc *ts_dev)
/* The steps1 … end and bit 0 for TS_Charge */
stepenable
=
(
1
<<
(
end_step
+
2
))
-
1
;
ts_dev
->
step_mask
=
stepenable
;
am335x_tsc_se_set
(
ts_dev
->
mfd_tscadc
,
ts_dev
->
step_mask
);
am335x_tsc_se_set
_cache
(
ts_dev
->
mfd_tscadc
,
ts_dev
->
step_mask
);
}
static
void
titsc_read_coordinates
(
struct
titsc
*
ts_dev
,
...
...
@@ -322,7 +322,7 @@ static irqreturn_t titsc_irq(int irq, void *dev)
if
(
irqclr
)
{
titsc_writel
(
ts_dev
,
REG_IRQSTATUS
,
irqclr
);
am335x_tsc_se_set
(
ts_dev
->
mfd_tscadc
,
ts_dev
->
step_mask
);
am335x_tsc_se_set
_cache
(
ts_dev
->
mfd_tscadc
,
ts_dev
->
step_mask
);
return
IRQ_HANDLED
;
}
return
IRQ_NONE
;
...
...
drivers/mfd/ti_am335x_tscadc.c
View file @
28b4c294
...
...
@@ -24,6 +24,7 @@
#include <linux/pm_runtime.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/sched.h>
#include <linux/mfd/ti_am335x_tscadc.h>
...
...
@@ -48,32 +49,79 @@ static const struct regmap_config tscadc_regmap_config = {
.
val_bits
=
32
,
};
void
am335x_tsc_se_
update
(
struct
ti_tscadc_dev
*
tsadc
)
void
am335x_tsc_se_
set_cache
(
struct
ti_tscadc_dev
*
tsadc
,
u32
val
)
{
tscadc_writel
(
tsadc
,
REG_SE
,
tsadc
->
reg_se_cache
);
unsigned
long
flags
;
spin_lock_irqsave
(
&
tsadc
->
reg_lock
,
flags
);
tsadc
->
reg_se_cache
=
val
;
if
(
tsadc
->
adc_waiting
)
wake_up
(
&
tsadc
->
reg_se_wait
);
else
if
(
!
tsadc
->
adc_in_use
)
tscadc_writel
(
tsadc
,
REG_SE
,
val
);
spin_unlock_irqrestore
(
&
tsadc
->
reg_lock
,
flags
);
}
EXPORT_SYMBOL_GPL
(
am335x_tsc_se_set_cache
);
static
void
am335x_tscadc_need_adc
(
struct
ti_tscadc_dev
*
tsadc
)
{
DEFINE_WAIT
(
wait
);
u32
reg
;
/*
* disable TSC steps so it does not run while the ADC is using it. If
* write 0 while it is running (it just started or was already running)
* then it completes all steps that were enabled and stops then.
*/
tscadc_writel
(
tsadc
,
REG_SE
,
0
);
reg
=
tscadc_readl
(
tsadc
,
REG_ADCFSM
);
if
(
reg
&
SEQ_STATUS
)
{
tsadc
->
adc_waiting
=
true
;
prepare_to_wait
(
&
tsadc
->
reg_se_wait
,
&
wait
,
TASK_UNINTERRUPTIBLE
);
spin_unlock_irq
(
&
tsadc
->
reg_lock
);
schedule
();
spin_lock_irq
(
&
tsadc
->
reg_lock
);
finish_wait
(
&
tsadc
->
reg_se_wait
,
&
wait
);
reg
=
tscadc_readl
(
tsadc
,
REG_ADCFSM
);
WARN_ON
(
reg
&
SEQ_STATUS
);
tsadc
->
adc_waiting
=
false
;
}
tsadc
->
adc_in_use
=
true
;
}
void
am335x_tsc_se_set_once
(
struct
ti_tscadc_dev
*
tsadc
,
u32
val
)
{
spin_lock_irq
(
&
tsadc
->
reg_lock
);
am335x_tscadc_need_adc
(
tsadc
);
tscadc_writel
(
tsadc
,
REG_SE
,
val
);
spin_unlock_irq
(
&
tsadc
->
reg_lock
);
}
EXPORT_SYMBOL_GPL
(
am335x_tsc_se_
updat
e
);
EXPORT_SYMBOL_GPL
(
am335x_tsc_se_
set_onc
e
);
void
am335x_tsc_se_
set
(
struct
ti_tscadc_dev
*
tsadc
,
u32
val
)
void
am335x_tsc_se_
adc_done
(
struct
ti_tscadc_dev
*
tsadc
)
{
unsigned
long
flags
;
spin_lock_irqsave
(
&
tsadc
->
reg_lock
,
flags
);
tsadc
->
reg_se_cache
=
tscadc_readl
(
tsadc
,
REG_SE
);
tsadc
->
reg_se_cache
|=
val
;
am335x_tsc_se_update
(
tsadc
);
tsadc
->
adc_in_use
=
false
;
tscadc_writel
(
tsadc
,
REG_SE
,
tsadc
->
reg_se_cache
);
spin_unlock_irqrestore
(
&
tsadc
->
reg_lock
,
flags
);
}
EXPORT_SYMBOL_GPL
(
am335x_tsc_se_
set
);
EXPORT_SYMBOL_GPL
(
am335x_tsc_se_
adc_done
);
void
am335x_tsc_se_clr
(
struct
ti_tscadc_dev
*
tsadc
,
u32
val
)
{
unsigned
long
flags
;
spin_lock_irqsave
(
&
tsadc
->
reg_lock
,
flags
);
tsadc
->
reg_se_cache
=
tscadc_readl
(
tsadc
,
REG_SE
);
tsadc
->
reg_se_cache
&=
~
val
;
am335x_tsc_se_update
(
tsadc
);
tscadc_writel
(
tsadc
,
REG_SE
,
tsadc
->
reg_se_cache
);
spin_unlock_irqrestore
(
&
tsadc
->
reg_lock
,
flags
);
}
EXPORT_SYMBOL_GPL
(
am335x_tsc_se_clr
);
...
...
@@ -181,6 +229,8 @@ static int ti_tscadc_probe(struct platform_device *pdev)
}
spin_lock_init
(
&
tscadc
->
reg_lock
);
init_waitqueue_head
(
&
tscadc
->
reg_se_wait
);
pm_runtime_enable
(
&
pdev
->
dev
);
pm_runtime_get_sync
(
&
pdev
->
dev
);
...
...
@@ -302,7 +352,6 @@ static int tscadc_resume(struct device *dev)
if
(
tscadc_dev
->
tsc_cell
!=
-
1
)
tscadc_idle_config
(
tscadc_dev
);
am335x_tsc_se_update
(
tscadc_dev
);
restore
=
tscadc_readl
(
tscadc_dev
,
REG_CTRL
);
tscadc_writel
(
tscadc_dev
,
REG_CTRL
,
(
restore
|
CNTRLREG_TSCSSENB
));
...
...
include/linux/mfd/ti_am335x_tscadc.h
View file @
28b4c294
...
...
@@ -159,6 +159,9 @@ struct ti_tscadc_dev {
int
adc_cell
;
/* -1 if not used */
struct
mfd_cell
cells
[
TSCADC_CELLS
];
u32
reg_se_cache
;
bool
adc_waiting
;
bool
adc_in_use
;
wait_queue_head_t
reg_se_wait
;
spinlock_t
reg_lock
;
unsigned
int
clk_div
;
...
...
@@ -176,8 +179,9 @@ static inline struct ti_tscadc_dev *ti_tscadc_dev_get(struct platform_device *p)
return
*
tscadc_dev
;
}
void
am335x_tsc_se_
update
(
struct
ti_tscadc_dev
*
tsadc
);
void
am335x_tsc_se_set
(
struct
ti_tscadc_dev
*
tsadc
,
u32
val
);
void
am335x_tsc_se_
set_cache
(
struct
ti_tscadc_dev
*
tsadc
,
u32
val
);
void
am335x_tsc_se_set
_once
(
struct
ti_tscadc_dev
*
tsadc
,
u32
val
);
void
am335x_tsc_se_clr
(
struct
ti_tscadc_dev
*
tsadc
,
u32
val
);
void
am335x_tsc_se_adc_done
(
struct
ti_tscadc_dev
*
tsadc
);
#endif
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