Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
OpenHarmony
kernel_linux
提交
6a84872a
K
kernel_linux
项目概览
OpenHarmony
/
kernel_linux
上一次同步 4 年多
通知
15
Star
8
Fork
2
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
DevOps
流水线
流水线任务
计划
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
K
kernel_linux
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
DevOps
DevOps
流水线
流水线任务
计划
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
流水线任务
提交
Issue看板
提交
6a84872a
编写于
5月 22, 2014
作者:
N
Nicolas Ferre
浏览文件
操作
浏览文件
下载
差异文件
Merge branch 'at91-3.16-cleanup' into at91-3.16-dt3
上级
d82b4013
138e8f1c
变更
74
显示空白变更内容
内联
并排
Showing
74 changed file
with
1790 addition
and
791 deletion
+1790
-791
Documentation/devicetree/bindings/clock/at91-clock.txt
Documentation/devicetree/bindings/clock/at91-clock.txt
+119
-9
MAINTAINERS
MAINTAINERS
+0
-6
arch/arm/Kconfig
arch/arm/Kconfig
+0
-1
arch/arm/boot/dts/at91-cosino_mega2560.dts
arch/arm/boot/dts/at91-cosino_mega2560.dts
+0
-5
arch/arm/boot/dts/at91-sama5d3_xplained.dts
arch/arm/boot/dts/at91-sama5d3_xplained.dts
+8
-0
arch/arm/boot/dts/at91sam9261.dtsi
arch/arm/boot/dts/at91sam9261.dtsi
+21
-2
arch/arm/boot/dts/at91sam9261ek.dts
arch/arm/boot/dts/at91sam9261ek.dts
+4
-0
arch/arm/boot/dts/at91sam9rl.dtsi
arch/arm/boot/dts/at91sam9rl.dtsi
+39
-7
arch/arm/boot/dts/at91sam9rlek.dts
arch/arm/boot/dts/at91sam9rlek.dts
+9
-0
arch/arm/boot/dts/sama5d3.dtsi
arch/arm/boot/dts/sama5d3.dtsi
+55
-6
arch/arm/boot/dts/sama5d3xcm.dtsi
arch/arm/boot/dts/sama5d3xcm.dtsi
+8
-0
arch/arm/configs/at91sam9g45_defconfig
arch/arm/configs/at91sam9g45_defconfig
+2
-1
arch/arm/configs/at91sam9rl_defconfig
arch/arm/configs/at91sam9rl_defconfig
+2
-1
arch/arm/configs/sama5_defconfig
arch/arm/configs/sama5_defconfig
+0
-1
arch/arm/mach-at91/at91rm9200_devices.c
arch/arm/mach-at91/at91rm9200_devices.c
+1
-0
arch/arm/mach-at91/at91sam9260_devices.c
arch/arm/mach-at91/at91sam9260_devices.c
+1
-11
arch/arm/mach-at91/at91sam9261_devices.c
arch/arm/mach-at91/at91sam9261_devices.c
+1
-1
arch/arm/mach-at91/at91sam9263_devices.c
arch/arm/mach-at91/at91sam9263_devices.c
+1
-0
arch/arm/mach-at91/at91sam9g45.c
arch/arm/mach-at91/at91sam9g45.c
+1
-1
arch/arm/mach-at91/at91sam9g45_devices.c
arch/arm/mach-at91/at91sam9g45_devices.c
+2
-62
arch/arm/mach-at91/at91sam9rl.c
arch/arm/mach-at91/at91sam9rl.c
+7
-0
arch/arm/mach-at91/at91sam9rl_devices.c
arch/arm/mach-at91/at91sam9rl_devices.c
+60
-24
arch/arm/mach-at91/board-1arm.c
arch/arm/mach-at91/board-1arm.c
+1
-1
arch/arm/mach-at91/board-afeb-9260v1.c
arch/arm/mach-at91/board-afeb-9260v1.c
+1
-0
arch/arm/mach-at91/board-cam60.c
arch/arm/mach-at91/board-cam60.c
+1
-0
arch/arm/mach-at91/board-carmeva.c
arch/arm/mach-at91/board-carmeva.c
+1
-0
arch/arm/mach-at91/board-cpu9krea.c
arch/arm/mach-at91/board-cpu9krea.c
+1
-0
arch/arm/mach-at91/board-cpuat91.c
arch/arm/mach-at91/board-cpuat91.c
+2
-0
arch/arm/mach-at91/board-csb337.c
arch/arm/mach-at91/board-csb337.c
+1
-1
arch/arm/mach-at91/board-csb637.c
arch/arm/mach-at91/board-csb637.c
+1
-0
arch/arm/mach-at91/board-eb9200.c
arch/arm/mach-at91/board-eb9200.c
+1
-0
arch/arm/mach-at91/board-ecbat91.c
arch/arm/mach-at91/board-ecbat91.c
+1
-0
arch/arm/mach-at91/board-eco920.c
arch/arm/mach-at91/board-eco920.c
+2
-0
arch/arm/mach-at91/board-flexibity.c
arch/arm/mach-at91/board-flexibity.c
+1
-0
arch/arm/mach-at91/board-foxg20.c
arch/arm/mach-at91/board-foxg20.c
+1
-0
arch/arm/mach-at91/board-gsia18s.c
arch/arm/mach-at91/board-gsia18s.c
+1
-0
arch/arm/mach-at91/board-kafa.c
arch/arm/mach-at91/board-kafa.c
+1
-0
arch/arm/mach-at91/board-kb9202.c
arch/arm/mach-at91/board-kb9202.c
+1
-0
arch/arm/mach-at91/board-pcontrol-g20.c
arch/arm/mach-at91/board-pcontrol-g20.c
+1
-0
arch/arm/mach-at91/board-picotux200.c
arch/arm/mach-at91/board-picotux200.c
+1
-0
arch/arm/mach-at91/board-rm9200ek.c
arch/arm/mach-at91/board-rm9200ek.c
+1
-0
arch/arm/mach-at91/board-rsi-ews.c
arch/arm/mach-at91/board-rsi-ews.c
+1
-0
arch/arm/mach-at91/board-sam9-l9260.c
arch/arm/mach-at91/board-sam9-l9260.c
+1
-0
arch/arm/mach-at91/board-sam9260ek.c
arch/arm/mach-at91/board-sam9260ek.c
+1
-0
arch/arm/mach-at91/board-sam9261ek.c
arch/arm/mach-at91/board-sam9261ek.c
+1
-0
arch/arm/mach-at91/board-sam9263ek.c
arch/arm/mach-at91/board-sam9263ek.c
+1
-0
arch/arm/mach-at91/board-sam9g20ek.c
arch/arm/mach-at91/board-sam9g20ek.c
+1
-0
arch/arm/mach-at91/board-sam9m10g45ek.c
arch/arm/mach-at91/board-sam9m10g45ek.c
+4
-13
arch/arm/mach-at91/board-sam9rlek.c
arch/arm/mach-at91/board-sam9rlek.c
+10
-7
arch/arm/mach-at91/board-snapper9260.c
arch/arm/mach-at91/board-snapper9260.c
+1
-0
arch/arm/mach-at91/board-stamp9g20.c
arch/arm/mach-at91/board-stamp9g20.c
+1
-0
arch/arm/mach-at91/board-yl-9200.c
arch/arm/mach-at91/board-yl-9200.c
+1
-0
arch/arm/mach-at91/board.h
arch/arm/mach-at91/board.h
+0
-3
arch/arm/mach-at91/gpio.c
arch/arm/mach-at91/gpio.c
+1
-0
arch/arm/mach-at91/gpio.h
arch/arm/mach-at91/gpio.h
+0
-8
arch/arm/mach-at91/include/mach/at91_adc.h
arch/arm/mach-at91/include/mach/at91_adc.h
+0
-107
arch/arm/mach-at91/include/mach/hardware.h
arch/arm/mach-at91/include/mach/hardware.h
+15
-0
arch/arm/mach-at91/leds.c
arch/arm/mach-at91/leds.c
+1
-0
arch/arm/mach-at91/pm.c
arch/arm/mach-at91/pm.c
+1
-0
drivers/clk/at91/Makefile
drivers/clk/at91/Makefile
+2
-2
drivers/clk/at91/clk-main.c
drivers/clk/at91/clk-main.c
+514
-63
drivers/clk/at91/clk-slow.c
drivers/clk/at91/clk-slow.c
+467
-0
drivers/clk/at91/pmc.c
drivers/clk/at91/pmc.c
+17
-0
drivers/clk/at91/pmc.h
drivers/clk/at91/pmc.h
+9
-0
drivers/clk/at91/sckc.c
drivers/clk/at91/sckc.c
+57
-0
drivers/clk/at91/sckc.h
drivers/clk/at91/sckc.h
+22
-0
drivers/iio/adc/at91_adc.c
drivers/iio/adc/at91_adc.c
+292
-48
drivers/input/touchscreen/Kconfig
drivers/input/touchscreen/Kconfig
+0
-12
drivers/input/touchscreen/Makefile
drivers/input/touchscreen/Makefile
+0
-1
drivers/input/touchscreen/atmel_tsadcc.c
drivers/input/touchscreen/atmel_tsadcc.c
+0
-358
include/linux/clk/at91_pmc.h
include/linux/clk/at91_pmc.h
+1
-0
include/linux/platform_data/at91_adc.h
include/linux/platform_data/at91_adc.h
+6
-21
include/linux/platform_data/atmel.h
include/linux/platform_data/atmel.h
+0
-7
sound/soc/atmel/sam9g20_wm8731.c
sound/soc/atmel/sam9g20_wm8731.c
+0
-1
未找到文件。
Documentation/devicetree/bindings/clock/at91-clock.txt
浏览文件 @
6a84872a
...
...
@@ -6,6 +6,16 @@ This binding uses the common clock binding[1].
Required properties:
- compatible : shall be one of the following:
"atmel,at91sam9x5-sckc":
at91 SCKC (Slow Clock Controller)
This node contains the slow clock definitions.
"atmel,at91sam9x5-clk-slow-osc":
at91 slow oscillator
"atmel,at91sam9x5-clk-slow-rc-osc":
at91 internal slow RC oscillator
"atmel,at91rm9200-pmc" or
"atmel,at91sam9g45-pmc" or
"atmel,at91sam9n12-pmc" or
...
...
@@ -15,8 +25,18 @@ Required properties:
All at91 specific clocks (clocks defined below) must be child
node of the PMC node.
"atmel,at91sam9x5-clk-slow" (under sckc node)
or
"atmel,at91sam9260-clk-slow" (under pmc node):
at91 slow clk
"atmel,at91rm9200-clk-main-osc"
"atmel,at91sam9x5-clk-main-rc-osc"
at91 main clk sources
"atmel,at91sam9x5-clk-main"
"atmel,at91rm9200-clk-main":
at91 main
oscillator
at91 main
clock
"atmel,at91rm9200-clk-master" or
"atmel,at91sam9x5-clk-master":
...
...
@@ -54,6 +74,63 @@ Required properties:
"atmel,at91sam9x5-clk-utmi":
at91 utmi clock
Required properties for SCKC node:
- reg : defines the IO memory reserved for the SCKC.
- #size-cells : shall be 0 (reg is used to encode clk id).
- #address-cells : shall be 1 (reg is used to encode clk id).
For example:
sckc: sckc@fffffe50 {
compatible = "atmel,sama5d3-pmc";
reg = <0xfffffe50 0x4>
#size-cells = <0>;
#address-cells = <1>;
/* put at91 slow clocks here */
};
Required properties for internal slow RC oscillator:
- #clock-cells : from common clock binding; shall be set to 0.
- clock-frequency : define the internal RC oscillator frequency.
Optional properties:
- clock-accuracy : define the internal RC oscillator accuracy.
For example:
slow_rc_osc: slow_rc_osc {
compatible = "atmel,at91sam9x5-clk-slow-rc-osc";
clock-frequency = <32768>;
clock-accuracy = <50000000>;
};
Required properties for slow oscillator:
- #clock-cells : from common clock binding; shall be set to 0.
- clocks : shall encode the main osc source clk sources (see atmel datasheet).
Optional properties:
- atmel,osc-bypass : boolean property. Set this when a clock signal is directly
provided on XIN.
For example:
slow_osc: slow_osc {
compatible = "atmel,at91rm9200-clk-slow-osc";
#clock-cells = <0>;
clocks = <&slow_xtal>;
};
Required properties for slow clock:
- #clock-cells : from common clock binding; shall be set to 0.
- clocks : shall encode the slow clk sources (see atmel datasheet).
For example:
clk32k: slck {
compatible = "atmel,at91sam9x5-clk-slow";
#clock-cells = <0>;
clocks = <&slow_rc_osc &slow_osc>;
};
Required properties for PMC node:
- reg : defines the IO memory reserved for the PMC.
- #size-cells : shall be 0 (reg is used to encode clk id).
...
...
@@ -85,24 +162,57 @@ For example:
/* put at91 clocks here */
};
Required properties for main clock internal RC oscillator:
- interrupt-parent : must reference the PMC node.
- interrupts : shall be set to "<0>".
- clock-frequency : define the internal RC oscillator frequency.
Optional properties:
- clock-accuracy : define the internal RC oscillator accuracy.
For example:
main_rc_osc: main_rc_osc {
compatible = "atmel,at91sam9x5-clk-main-rc-osc";
interrupt-parent = <&pmc>;
interrupts = <0>;
clock-frequency = <12000000>;
clock-accuracy = <50000000>;
};
Required properties for main clock oscillator:
- interrupt-parent : must reference the PMC node.
- interrupts : shall be set to "<0>".
- #clock-cells : from common clock binding; shall be set to 0.
- clocks : shall encode the main osc source clk sources (see atmel datasheet).
Optional properties:
- atmel,osc-bypass : boolean property. Specified if a clock signal is provided
on XIN.
clock signal is directly provided on XIN pin.
For example:
main_osc: main_osc {
compatible = "atmel,at91rm9200-clk-main-osc";
interrupt-parent = <&pmc>;
interrupts = <0>;
#clock-cells = <0>;
clocks = <&main_xtal>;
};
Required properties for main clock:
- interrupt-parent : must reference the PMC node.
- interrupts : shall be set to "<0>".
- #clock-cells : from common clock binding; shall be set to 0.
- clocks (optional if clock-frequency is provided) : shall be the slow clock
phandle. This clock is used to calculate the main clock rate if
"clock-frequency" is not provided.
- clock-frequency : the main oscillator frequency.Prefer the use of
"clock-frequency" over automatic clock rate calculation.
- clocks : shall encode the main clk sources (see atmel datasheet).
For example:
main: mainck {
compatible = "atmel,at91
rm9200
-clk-main";
compatible = "atmel,at91
sam9x5
-clk-main";
interrupt-parent = <&pmc>;
interrupts = <0>;
#clock-cells = <0>;
clocks = <&ck32k>;
clock-frequency = <18432000>;
clocks = <&main_rc_osc &main_osc>;
};
Required properties for master clock:
...
...
MAINTAINERS
浏览文件 @
6a84872a
...
...
@@ -1617,12 +1617,6 @@ S: Supported
F: drivers/misc/atmel_tclib.c
F: drivers/clocksource/tcb_clksrc.c
ATMEL TSADCC DRIVER
M: Josh Wu <josh.wu@atmel.com>
L: linux-input@vger.kernel.org
S: Supported
F: drivers/input/touchscreen/atmel_tsadcc.c
ATMEL USBA UDC DRIVER
M: Nicolas Ferre <nicolas.ferre@atmel.com>
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
...
...
arch/arm/Kconfig
浏览文件 @
6a84872a
...
...
@@ -376,7 +376,6 @@ config ARCH_AT91
select ARCH_REQUIRE_GPIOLIB
select CLKDEV_LOOKUP
select IRQ_DOMAIN
select NEED_MACH_GPIO_H
select NEED_MACH_IO_H if PCCARD
select PINCTRL
select PINCTRL_AT91 if USE_OF
...
...
arch/arm/boot/dts/at91-cosino_mega2560.dts
浏览文件 @
6a84872a
...
...
@@ -32,11 +32,6 @@
status
=
"okay"
;
};
tsadcc
:
tsadcc
@
f804c000
{
status
=
"okay"
;
};
rtc
@
fffffeb0
{
status
=
"okay"
;
};
...
...
arch/arm/boot/dts/at91-sama5d3_xplained.dts
浏览文件 @
6a84872a
...
...
@@ -21,6 +21,14 @@
reg
=
<
0x20000000
0x10000000
>;
};
slow_xtal
{
clock
-
frequency
=
<
32768
>;
};
main_xtal
{
clock
-
frequency
=
<
12000000
>;
};
ahb
{
apb
{
mmc0
:
mmc
@
f0000000
{
...
...
arch/arm/boot/dts/at91sam9261.dtsi
浏览文件 @
6a84872a
...
...
@@ -45,6 +45,18 @@
reg
=
<
0x20000000
0x08000000
>;
};
main_xtal
:
main_xtal
{
compatible
=
"fixed-clock"
;
#
clock
-
cells
=
<
0
>;
clock
-
frequency
=
<
0
>;
};
slow_xtal
:
slow_xtal
{
compatible
=
"fixed-clock"
;
#
clock
-
cells
=
<
0
>;
clock
-
frequency
=
<
0
>;
};
ahb
{
compatible
=
"simple-bus"
;
#
address
-
cells
=
<
1
>;
...
...
@@ -524,17 +536,24 @@
#
size
-
cells
=
<
0
>;
#
interrupt
-
cells
=
<
1
>;
clk32k
:
slck
{
slow_rc_osc
:
slow_rc_osc
{
compatible
=
"fixed-clock"
;
#
clock
-
cells
=
<
0
>;
clock
-
frequency
=
<
32768
>;
clock
-
accuracy
=
<
50000000
>;
};
clk32k
:
slck
{
compatible
=
"atmel,at91sam9260-clk-slow"
;
#
clock
-
cells
=
<
0
>;
clocks
=
<&
slow_rc_osc
&
slow_xtal
>;
};
main
:
mainck
{
compatible
=
"atmel,at91rm9200-clk-main"
;
#
clock
-
cells
=
<
0
>;
interrupts
-
extended
=
<&
pmc
AT91_PMC_MOSCS
>;
clocks
=
<&
clk32k
>;
clocks
=
<&
main_xtal
>;
};
plla
:
pllack
{
...
...
arch/arm/boot/dts/at91sam9261ek.dts
浏览文件 @
6a84872a
...
...
@@ -20,6 +20,10 @@
reg
=
<
0x20000000
0x4000000
>;
};
main_xtal
{
clock
-
frequency
=
<
18432000
>;
};
clocks
{
#
address
-
cells
=
<
1
>;
#
size
-
cells
=
<
1
>;
...
...
arch/arm/boot/dts/at91sam9rl.dtsi
浏览文件 @
6a84872a
...
...
@@ -48,6 +48,18 @@
reg
=
<
0x20000000
0x04000000
>;
};
slow_xtal
:
slow_xtal
{
compatible
=
"fixed-clock"
;
#
clock
-
cells
=
<
0
>;
clock
-
frequency
=
<
0
>;
};
main_xtal
:
main_xtal
{
compatible
=
"fixed-clock"
;
#
clock
-
cells
=
<
0
>;
clock
-
frequency
=
<
0
>;
};
ahb
{
compatible
=
"simple-bus"
;
#
address
-
cells
=
<
1
>;
...
...
@@ -548,17 +560,11 @@
#
size
-
cells
=
<
0
>;
#
interrupt
-
cells
=
<
1
>;
clk32k
:
slck
{
compatible
=
"fixed-clock"
;
#
clock
-
cells
=
<
0
>;
clock
-
frequency
=
<
32768
>;
};
main
:
mainck
{
compatible
=
"atmel,at91rm9200-clk-main"
;
#
clock
-
cells
=
<
0
>;
interrupts
-
extended
=
<&
pmc
AT91_PMC_MOSCS
>;
clocks
=
<&
clk32k
>;
clocks
=
<&
main_xtal
>;
};
plla
:
pllack
{
...
...
@@ -769,6 +775,32 @@
interrupts
=
<
1
IRQ_TYPE_LEVEL_HIGH
7
>;
status
=
"disabled"
;
};
sckc
@
fffffd50
{
compatible
=
"atmel,at91sam9x5-sckc"
;
reg
=
<
0xfffffd50
0x4
>;
slow_osc
:
slow_osc
{
compatible
=
"atmel,at91sam9x5-clk-slow-osc"
;
#
clock
-
cells
=
<
0
>;
atmel
,
startup
-
time
-
usec
=
<
1200000
>;
clocks
=
<&
slow_xtal
>;
};
slow_rc_osc
:
slow_rc_osc
{
compatible
=
"atmel,at91sam9x5-clk-slow-rc-osc"
;
#
clock
-
cells
=
<
0
>;
atmel
,
startup
-
time
-
usec
=
<
75
>;
clock
-
frequency
=
<
32768
>;
clock
-
accuracy
=
<
50000000
>;
};
clk32k
:
slck
{
compatible
=
"atmel,at91sam9x5-clk-slow"
;
#
clock
-
cells
=
<
0
>;
clocks
=
<&
slow_rc_osc
&
slow_osc
>;
};
};
};
};
...
...
arch/arm/boot/dts/at91sam9rlek.dts
浏览文件 @
6a84872a
...
...
@@ -20,6 +20,15 @@
reg
=
<
0x20000000
0x4000000
>;
};
slow_xtal
{
clock
-
frequency
=
<
32768
>;
};
main_xtal
{
clock
-
frequency
=
<
12000000
>;
};
clocks
{
#
address
-
cells
=
<
1
>;
#
size
-
cells
=
<
1
>;
...
...
arch/arm/boot/dts/sama5d3.dtsi
浏览文件 @
6a84872a
...
...
@@ -58,6 +58,18 @@
reg
=
<
0x20000000
0x8000000
>;
};
slow_xtal
:
slow_xtal
{
compatible
=
"fixed-clock"
;
#
clock
-
cells
=
<
0
>;
clock
-
frequency
=
<
0
>;
};
main_xtal
:
main_xtal
{
compatible
=
"fixed-clock"
;
#
clock
-
cells
=
<
0
>;
clock
-
frequency
=
<
0
>;
};
clocks
{
adc_op_clk
:
adc_op_clk
{
compatible
=
"fixed-clock"
;
...
...
@@ -749,18 +761,29 @@
#
size
-
cells
=
<
0
>;
#
interrupt
-
cells
=
<
1
>;
clk32k
:
slck
{
compatible
=
"
fixed-clock
"
;
main_rc_osc
:
main_rc_osc
{
compatible
=
"
atmel,at91sam9x5-clk-main-rc-osc
"
;
#
clock
-
cells
=
<
0
>;
clock
-
frequency
=
<
32768
>;
interrupt
-
parent
=
<&
pmc
>;
interrupts
=
<
AT91_PMC_MOSCRCS
>;
clock
-
frequency
=
<
12000000
>;
clock
-
accuracy
=
<
50000000
>;
};
main
:
mainck
{
compatible
=
"atmel,at91rm9200-clk-main"
;
main
_osc
:
main_osc
{
compatible
=
"atmel,at91rm9200-clk-main
-osc
"
;
#
clock
-
cells
=
<
0
>;
interrupt
-
parent
=
<&
pmc
>;
interrupts
=
<
AT91_PMC_MOSCS
>;
clocks
=
<&
clk32k
>;
clocks
=
<&
main_xtal
>;
};
main
:
mainck
{
compatible
=
"atmel,at91sam9x5-clk-main"
;
#
clock
-
cells
=
<
0
>;
interrupt
-
parent
=
<&
pmc
>;
interrupts
=
<
AT91_PMC_MOSCSELS
>;
clocks
=
<&
main_rc_osc
&
main_osc
>;
};
plla
:
pllack
{
...
...
@@ -1089,6 +1112,32 @@
status
=
"disabled"
;
};
sckc
@
fffffe50
{
compatible
=
"atmel,at91sam9x5-sckc"
;
reg
=
<
0xfffffe50
0x4
>;
slow_rc_osc
:
slow_rc_osc
{
compatible
=
"atmel,at91sam9x5-clk-slow-rc-osc"
;
#
clock
-
cells
=
<
0
>;
clock
-
frequency
=
<
32768
>;
clock
-
accuracy
=
<
50000000
>;
atmel
,
startup
-
time
-
usec
=
<
75
>;
};
slow_osc
:
slow_osc
{
compatible
=
"atmel,at91sam9x5-clk-slow-osc"
;
#
clock
-
cells
=
<
0
>;
clocks
=
<&
slow_xtal
>;
atmel
,
startup
-
time
-
usec
=
<
1200000
>;
};
clk32k
:
slowck
{
compatible
=
"atmel,at91sam9x5-clk-slow"
;
#
clock
-
cells
=
<
0
>;
clocks
=
<&
slow_rc_osc
&
slow_osc
>;
};
};
rtc
@
fffffeb0
{
compatible
=
"atmel,at91rm9200-rtc"
;
reg
=
<
0xfffffeb0
0x30
>;
...
...
arch/arm/boot/dts/sama5d3xcm.dtsi
浏览文件 @
6a84872a
...
...
@@ -18,6 +18,14 @@
reg = <0x20000000 0x20000000>;
};
slow_xtal {
clock-frequency = <32768>;
};
main_xtal {
clock-frequency = <12000000>;
};
ahb {
apb {
spi0: spi@f0004000 {
...
...
arch/arm/configs/at91sam9g45_defconfig
浏览文件 @
6a84872a
...
...
@@ -83,7 +83,6 @@ CONFIG_KEYBOARD_GPIO=y
# CONFIG_INPUT_MOUSE is not set
CONFIG_INPUT_TOUCHSCREEN=y
CONFIG_TOUCHSCREEN_ATMEL_MXT=m
CONFIG_TOUCHSCREEN_ATMEL_TSADCC=y
# CONFIG_SERIO is not set
# CONFIG_LEGACY_PTYS is not set
CONFIG_SERIAL_ATMEL=y
...
...
@@ -146,6 +145,8 @@ CONFIG_DMADEVICES=y
CONFIG_AT_HDMAC=y
CONFIG_DMATEST=m
# CONFIG_IOMMU_SUPPORT is not set
CONFIG_IIO=y
CONFIG_AT91_ADC=y
CONFIG_EXT4_FS=y
CONFIG_FANOTIFY=y
CONFIG_VFAT_FS=y
...
...
arch/arm/configs/at91sam9rl_defconfig
浏览文件 @
6a84872a
...
...
@@ -45,7 +45,6 @@ CONFIG_INPUT_EVDEV=y
# CONFIG_INPUT_KEYBOARD is not set
# CONFIG_INPUT_MOUSE is not set
CONFIG_INPUT_TOUCHSCREEN=y
CONFIG_TOUCHSCREEN_ATMEL_TSADCC=y
# CONFIG_SERIO is not set
CONFIG_SERIAL_ATMEL=y
CONFIG_SERIAL_ATMEL_CONSOLE=y
...
...
@@ -65,6 +64,8 @@ CONFIG_MMC=y
CONFIG_MMC_ATMELMCI=m
CONFIG_RTC_CLASS=y
CONFIG_RTC_DRV_AT91SAM9=y
CONFIG_IIO=y
CONFIG_AT91_ADC=y
CONFIG_EXT2_FS=y
CONFIG_MSDOS_FS=y
CONFIG_VFAT_FS=y
...
...
arch/arm/configs/sama5_defconfig
浏览文件 @
6a84872a
...
...
@@ -122,7 +122,6 @@ CONFIG_KEYBOARD_GPIO=y
# CONFIG_INPUT_MOUSE is not set
CONFIG_INPUT_TOUCHSCREEN=y
CONFIG_TOUCHSCREEN_ATMEL_MXT=y
CONFIG_TOUCHSCREEN_ATMEL_TSADCC=y
# CONFIG_SERIO is not set
CONFIG_LEGACY_PTY_COUNT=4
CONFIG_SERIAL_ATMEL=y
...
...
arch/arm/mach-at91/at91rm9200_devices.c
浏览文件 @
6a84872a
...
...
@@ -25,6 +25,7 @@
#include "board.h"
#include "generic.h"
#include "gpio.h"
/* --------------------------------------------------------------------
...
...
arch/arm/mach-at91/at91sam9260_devices.c
浏览文件 @
6a84872a
...
...
@@ -24,12 +24,11 @@
#include <mach/at91sam9260_matrix.h>
#include <mach/at91_matrix.h>
#include <mach/at91sam9_smc.h>
#include <mach/at91_adc.h>
#include <mach/hardware.h>
#include "board.h"
#include "generic.h"
#include "gpio.h"
/* --------------------------------------------------------------------
* USB Host
...
...
@@ -1325,13 +1324,6 @@ static struct at91_adc_trigger at91_adc_triggers[] = {
},
};
static
struct
at91_adc_reg_desc
at91_adc_register_g20
=
{
.
channel_base
=
AT91_ADC_CHR
(
0
),
.
drdy_mask
=
AT91_ADC_DRDY
,
.
status_register
=
AT91_ADC_SR
,
.
trigger_register
=
AT91_ADC_MR
,
};
void
__init
at91_add_device_adc
(
struct
at91_adc_data
*
data
)
{
if
(
!
data
)
...
...
@@ -1349,9 +1341,7 @@ void __init at91_add_device_adc(struct at91_adc_data *data)
if
(
data
->
use_external_triggers
)
at91_set_A_periph
(
AT91_PIN_PA22
,
0
);
data
->
num_channels
=
4
;
data
->
startup_time
=
10
;
data
->
registers
=
&
at91_adc_register_g20
;
data
->
trigger_number
=
4
;
data
->
trigger_list
=
at91_adc_triggers
;
...
...
arch/arm/mach-at91/at91sam9261_devices.c
浏览文件 @
6a84872a
...
...
@@ -29,7 +29,7 @@
#include "board.h"
#include "generic.h"
#include "gpio.h"
/* --------------------------------------------------------------------
* USB Host
...
...
arch/arm/mach-at91/at91sam9263_devices.c
浏览文件 @
6a84872a
...
...
@@ -28,6 +28,7 @@
#include "board.h"
#include "generic.h"
#include "gpio.h"
/* --------------------------------------------------------------------
...
...
arch/arm/mach-at91/at91sam9g45.c
浏览文件 @
6a84872a
...
...
@@ -182,7 +182,7 @@ static struct clk vdec_clk = {
static
struct
clk
adc_op_clk
=
{
.
name
=
"adc_op_clk"
,
.
type
=
CLK_TYPE_PERIPHERAL
,
.
rate_hz
=
132
00000
,
.
rate_hz
=
3
00000
,
};
/* AES/TDES/SHA clock - Only for sam9m11/sam9g56 */
...
...
arch/arm/mach-at91/at91sam9g45_devices.c
浏览文件 @
6a84872a
...
...
@@ -25,7 +25,6 @@
#include <linux/fb.h>
#include <video/atmel_lcdc.h>
#include <mach/at91_adc.h>
#include <mach/at91sam9g45.h>
#include <mach/at91sam9g45_matrix.h>
#include <mach/at91_matrix.h>
...
...
@@ -39,6 +38,7 @@
#include "board.h"
#include "generic.h"
#include "clock.h"
#include "gpio.h"
/* --------------------------------------------------------------------
...
...
@@ -1133,58 +1133,7 @@ static void __init at91_add_device_rtc(void) {}
/* --------------------------------------------------------------------
* Touchscreen
* -------------------------------------------------------------------- */
#if defined(CONFIG_TOUCHSCREEN_ATMEL_TSADCC) || defined(CONFIG_TOUCHSCREEN_ATMEL_TSADCC_MODULE)
static
u64
tsadcc_dmamask
=
DMA_BIT_MASK
(
32
);
static
struct
at91_tsadcc_data
tsadcc_data
;
static
struct
resource
tsadcc_resources
[]
=
{
[
0
]
=
{
.
start
=
AT91SAM9G45_BASE_TSC
,
.
end
=
AT91SAM9G45_BASE_TSC
+
SZ_16K
-
1
,
.
flags
=
IORESOURCE_MEM
,
},
[
1
]
=
{
.
start
=
NR_IRQS_LEGACY
+
AT91SAM9G45_ID_TSC
,
.
end
=
NR_IRQS_LEGACY
+
AT91SAM9G45_ID_TSC
,
.
flags
=
IORESOURCE_IRQ
,
}
};
static
struct
platform_device
at91sam9g45_tsadcc_device
=
{
.
name
=
"atmel_tsadcc"
,
.
id
=
-
1
,
.
dev
=
{
.
dma_mask
=
&
tsadcc_dmamask
,
.
coherent_dma_mask
=
DMA_BIT_MASK
(
32
),
.
platform_data
=
&
tsadcc_data
,
},
.
resource
=
tsadcc_resources
,
.
num_resources
=
ARRAY_SIZE
(
tsadcc_resources
),
};
void
__init
at91_add_device_tsadcc
(
struct
at91_tsadcc_data
*
data
)
{
if
(
!
data
)
return
;
at91_set_gpio_input
(
AT91_PIN_PD20
,
0
);
/* AD0_XR */
at91_set_gpio_input
(
AT91_PIN_PD21
,
0
);
/* AD1_XL */
at91_set_gpio_input
(
AT91_PIN_PD22
,
0
);
/* AD2_YT */
at91_set_gpio_input
(
AT91_PIN_PD23
,
0
);
/* AD3_TB */
tsadcc_data
=
*
data
;
platform_device_register
(
&
at91sam9g45_tsadcc_device
);
}
#else
void
__init
at91_add_device_tsadcc
(
struct
at91_tsadcc_data
*
data
)
{}
#endif
/* --------------------------------------------------------------------
* ADC
* ADC and touchscreen
* -------------------------------------------------------------------- */
#if IS_ENABLED(CONFIG_AT91_ADC)
...
...
@@ -1236,13 +1185,6 @@ static struct at91_adc_trigger at91_adc_triggers[] = {
},
};
static
struct
at91_adc_reg_desc
at91_adc_register_g45
=
{
.
channel_base
=
AT91_ADC_CHR
(
0
),
.
drdy_mask
=
AT91_ADC_DRDY
,
.
status_register
=
AT91_ADC_SR
,
.
trigger_register
=
0x08
,
};
void
__init
at91_add_device_adc
(
struct
at91_adc_data
*
data
)
{
if
(
!
data
)
...
...
@@ -1268,9 +1210,7 @@ void __init at91_add_device_adc(struct at91_adc_data *data)
if
(
data
->
use_external_triggers
)
at91_set_A_periph
(
AT91_PIN_PD28
,
0
);
data
->
num_channels
=
8
;
data
->
startup_time
=
40
;
data
->
registers
=
&
at91_adc_register_g45
;
data
->
trigger_number
=
4
;
data
->
trigger_list
=
at91_adc_triggers
;
...
...
arch/arm/mach-at91/at91sam9rl.c
浏览文件 @
6a84872a
...
...
@@ -153,6 +153,11 @@ static struct clk ac97_clk = {
.
pmc_mask
=
1
<<
AT91SAM9RL_ID_AC97C
,
.
type
=
CLK_TYPE_PERIPHERAL
,
};
static
struct
clk
adc_op_clk
=
{
.
name
=
"adc_op_clk"
,
.
type
=
CLK_TYPE_PERIPHERAL
,
.
rate_hz
=
1000000
,
};
static
struct
clk
*
periph_clocks
[]
__initdata
=
{
&
pioA_clk
,
...
...
@@ -178,6 +183,7 @@ static struct clk *periph_clocks[] __initdata = {
&
udphs_clk
,
&
lcdc_clk
,
&
ac97_clk
,
&
adc_op_clk
,
// irq0
};
...
...
@@ -216,6 +222,7 @@ static struct clk_lookup periph_clocks_lookups[] = {
CLKDEV_CON_DEV_ID
(
NULL
,
"fffff600.gpio"
,
&
pioB_clk
),
CLKDEV_CON_DEV_ID
(
NULL
,
"fffff800.gpio"
,
&
pioC_clk
),
CLKDEV_CON_DEV_ID
(
NULL
,
"fffffa00.gpio"
,
&
pioD_clk
),
CLKDEV_CON_ID
(
"adc_clk"
,
&
tsc_clk
),
};
static
struct
clk_lookup
usart_clocks_lookups
[]
=
{
...
...
arch/arm/mach-at91/at91sam9rl_devices.c
浏览文件 @
6a84872a
...
...
@@ -23,9 +23,11 @@
#include <mach/at91sam9_smc.h>
#include <mach/hardware.h>
#include <linux/platform_data/dma-atmel.h>
#include <linux/platform_data/at91_adc.h>
#include "board.h"
#include "generic.h"
#include "gpio.h"
/* --------------------------------------------------------------------
...
...
@@ -608,14 +610,13 @@ static void __init at91_add_device_tc(void) { }
/* --------------------------------------------------------------------
* Touchscreen
*
ADC and
Touchscreen
* -------------------------------------------------------------------- */
#if defined(CONFIG_TOUCHSCREEN_ATMEL_TSADCC) || defined(CONFIG_TOUCHSCREEN_ATMEL_TSADCC_MODULE)
static
u64
tsadcc_dmamask
=
DMA_BIT_MASK
(
32
);
static
struct
at91_tsadcc_data
tsadcc_data
;
#if IS_ENABLED(CONFIG_AT91_ADC)
static
struct
at91_adc_data
adc_data
;
static
struct
resource
tsadc
c_resources
[]
=
{
static
struct
resource
ad
c_resources
[]
=
{
[
0
]
=
{
.
start
=
AT91SAM9RL_BASE_TSC
,
.
end
=
AT91SAM9RL_BASE_TSC
+
SZ_16K
-
1
,
...
...
@@ -628,36 +629,71 @@ static struct resource tsadcc_resources[] = {
}
};
static
struct
platform_device
at91
sam9rl_tsadc
c_device
=
{
.
name
=
"atmel_tsadc
c"
,
static
struct
platform_device
at91
_ad
c_device
=
{
.
name
=
"at91sam9rl-ad
c"
,
.
id
=
-
1
,
.
dev
=
{
.
dma_mask
=
&
tsadcc_dmamask
,
.
coherent_dma_mask
=
DMA_BIT_MASK
(
32
),
.
platform_data
=
&
tsadcc_data
,
.
platform_data
=
&
adc_data
,
},
.
resource
=
tsadc
c_resources
,
.
num_resources
=
ARRAY_SIZE
(
tsadc
c_resources
),
.
resource
=
ad
c_resources
,
.
num_resources
=
ARRAY_SIZE
(
ad
c_resources
),
};
void
__init
at91_add_device_tsadcc
(
struct
at91_tsadcc_data
*
data
)
static
struct
at91_adc_trigger
at91_adc_triggers
[]
=
{
[
0
]
=
{
.
name
=
"external-rising"
,
.
value
=
1
,
.
is_external
=
true
,
},
[
1
]
=
{
.
name
=
"external-falling"
,
.
value
=
2
,
.
is_external
=
true
,
},
[
2
]
=
{
.
name
=
"external-any"
,
.
value
=
3
,
.
is_external
=
true
,
},
[
3
]
=
{
.
name
=
"continuous"
,
.
value
=
6
,
.
is_external
=
false
,
},
};
void
__init
at91_add_device_adc
(
struct
at91_adc_data
*
data
)
{
if
(
!
data
)
return
;
at91_set_A_periph
(
AT91_PIN_PA17
,
0
);
/* AD0_XR */
at91_set_A_periph
(
AT91_PIN_PA18
,
0
);
/* AD1_XL */
at91_set_A_periph
(
AT91_PIN_PA19
,
0
);
/* AD2_YT */
at91_set_A_periph
(
AT91_PIN_PA20
,
0
);
/* AD3_TB */
tsadcc_data
=
*
data
;
platform_device_register
(
&
at91sam9rl_tsadcc_device
);
if
(
test_bit
(
0
,
&
data
->
channels_used
))
at91_set_A_periph
(
AT91_PIN_PA17
,
0
);
if
(
test_bit
(
1
,
&
data
->
channels_used
))
at91_set_A_periph
(
AT91_PIN_PA18
,
0
);
if
(
test_bit
(
2
,
&
data
->
channels_used
))
at91_set_A_periph
(
AT91_PIN_PA19
,
0
);
if
(
test_bit
(
3
,
&
data
->
channels_used
))
at91_set_A_periph
(
AT91_PIN_PA20
,
0
);
if
(
test_bit
(
4
,
&
data
->
channels_used
))
at91_set_A_periph
(
AT91_PIN_PD6
,
0
);
if
(
test_bit
(
5
,
&
data
->
channels_used
))
at91_set_A_periph
(
AT91_PIN_PD7
,
0
);
if
(
data
->
use_external_triggers
)
at91_set_A_periph
(
AT91_PIN_PB15
,
0
);
data
->
startup_time
=
40
;
data
->
trigger_number
=
4
;
data
->
trigger_list
=
at91_adc_triggers
;
adc_data
=
*
data
;
platform_device_register
(
&
at91_adc_device
);
}
#else
void
__init
at91_add_device_
tsadcc
(
struct
at91_tsadc
c_data
*
data
)
{}
void
__init
at91_add_device_
adc
(
struct
at91_ad
c_data
*
data
)
{}
#endif
/* --------------------------------------------------------------------
* RTC
* -------------------------------------------------------------------- */
...
...
arch/arm/mach-at91/board-1arm.c
浏览文件 @
6a84872a
...
...
@@ -39,7 +39,7 @@
#include "at91_aic.h"
#include "board.h"
#include "generic.h"
#include "gpio.h"
static
void
__init
onearm_init_early
(
void
)
{
...
...
arch/arm/mach-at91/board-afeb-9260v1.c
浏览文件 @
6a84872a
...
...
@@ -46,6 +46,7 @@
#include "at91_aic.h"
#include "board.h"
#include "generic.h"
#include "gpio.h"
static
void
__init
afeb9260_init_early
(
void
)
...
...
arch/arm/mach-at91/board-cam60.c
浏览文件 @
6a84872a
...
...
@@ -44,6 +44,7 @@
#include "board.h"
#include "sam9_smc.h"
#include "generic.h"
#include "gpio.h"
static
void
__init
cam60_init_early
(
void
)
...
...
arch/arm/mach-at91/board-carmeva.c
浏览文件 @
6a84872a
...
...
@@ -39,6 +39,7 @@
#include "at91_aic.h"
#include "board.h"
#include "generic.h"
#include "gpio.h"
static
void
__init
carmeva_init_early
(
void
)
...
...
arch/arm/mach-at91/board-cpu9krea.c
浏览文件 @
6a84872a
...
...
@@ -48,6 +48,7 @@
#include "board.h"
#include "sam9_smc.h"
#include "generic.h"
#include "gpio.h"
static
void
__init
cpu9krea_init_early
(
void
)
{
...
...
arch/arm/mach-at91/board-cpuat91.c
浏览文件 @
6a84872a
...
...
@@ -43,6 +43,8 @@
#include "at91_aic.h"
#include "board.h"
#include "generic.h"
#include "gpio.h"
static
struct
gpio_led
cpuat91_leds
[]
=
{
{
...
...
arch/arm/mach-at91/board-csb337.c
浏览文件 @
6a84872a
...
...
@@ -42,7 +42,7 @@
#include "at91_aic.h"
#include "board.h"
#include "generic.h"
#include "gpio.h"
static
void
__init
csb337_init_early
(
void
)
{
...
...
arch/arm/mach-at91/board-csb637.c
浏览文件 @
6a84872a
...
...
@@ -39,6 +39,7 @@
#include "at91_aic.h"
#include "board.h"
#include "generic.h"
#include "gpio.h"
static
void
__init
csb637_init_early
(
void
)
...
...
arch/arm/mach-at91/board-eb9200.c
浏览文件 @
6a84872a
...
...
@@ -38,6 +38,7 @@
#include "at91_aic.h"
#include "board.h"
#include "generic.h"
#include "gpio.h"
static
void
__init
eb9200_init_early
(
void
)
...
...
arch/arm/mach-at91/board-ecbat91.c
浏览文件 @
6a84872a
...
...
@@ -42,6 +42,7 @@
#include "at91_aic.h"
#include "board.h"
#include "generic.h"
#include "gpio.h"
static
void
__init
ecb_at91init_early
(
void
)
...
...
arch/arm/mach-at91/board-eco920.c
浏览文件 @
6a84872a
...
...
@@ -31,6 +31,8 @@
#include "at91_aic.h"
#include "board.h"
#include "generic.h"
#include "gpio.h"
static
void
__init
eco920_init_early
(
void
)
{
...
...
arch/arm/mach-at91/board-flexibity.c
浏览文件 @
6a84872a
...
...
@@ -37,6 +37,7 @@
#include "at91_aic.h"
#include "board.h"
#include "generic.h"
#include "gpio.h"
static
void
__init
flexibity_init_early
(
void
)
{
...
...
arch/arm/mach-at91/board-foxg20.c
浏览文件 @
6a84872a
...
...
@@ -47,6 +47,7 @@
#include "board.h"
#include "sam9_smc.h"
#include "generic.h"
#include "gpio.h"
/*
* The FOX Board G20 hardware comes as the "Netus G20" board with
...
...
arch/arm/mach-at91/board-gsia18s.c
浏览文件 @
6a84872a
...
...
@@ -39,6 +39,7 @@
#include "generic.h"
#include "gsia18s.h"
#include "stamp9g20.h"
#include "gpio.h"
static
void
__init
gsia18s_init_early
(
void
)
{
...
...
arch/arm/mach-at91/board-kafa.c
浏览文件 @
6a84872a
...
...
@@ -39,6 +39,7 @@
#include "at91_aic.h"
#include "board.h"
#include "generic.h"
#include "gpio.h"
static
void
__init
kafa_init_early
(
void
)
...
...
arch/arm/mach-at91/board-kb9202.c
浏览文件 @
6a84872a
...
...
@@ -42,6 +42,7 @@
#include "at91_aic.h"
#include "board.h"
#include "generic.h"
#include "gpio.h"
static
void
__init
kb9202_init_early
(
void
)
...
...
arch/arm/mach-at91/board-pcontrol-g20.c
浏览文件 @
6a84872a
...
...
@@ -37,6 +37,7 @@
#include "sam9_smc.h"
#include "generic.h"
#include "stamp9g20.h"
#include "gpio.h"
static
void
__init
pcontrol_g20_init_early
(
void
)
...
...
arch/arm/mach-at91/board-picotux200.c
浏览文件 @
6a84872a
...
...
@@ -43,6 +43,7 @@
#include "at91_aic.h"
#include "board.h"
#include "generic.h"
#include "gpio.h"
static
void
__init
picotux200_init_early
(
void
)
...
...
arch/arm/mach-at91/board-rm9200ek.c
浏览文件 @
6a84872a
...
...
@@ -45,6 +45,7 @@
#include "at91_aic.h"
#include "board.h"
#include "generic.h"
#include "gpio.h"
static
void
__init
ek_init_early
(
void
)
...
...
arch/arm/mach-at91/board-rsi-ews.c
浏览文件 @
6a84872a
...
...
@@ -31,6 +31,7 @@
#include "at91_aic.h"
#include "board.h"
#include "generic.h"
#include "gpio.h"
static
void
__init
rsi_ews_init_early
(
void
)
{
...
...
arch/arm/mach-at91/board-sam9-l9260.c
浏览文件 @
6a84872a
...
...
@@ -43,6 +43,7 @@
#include "board.h"
#include "sam9_smc.h"
#include "generic.h"
#include "gpio.h"
static
void
__init
ek_init_early
(
void
)
...
...
arch/arm/mach-at91/board-sam9260ek.c
浏览文件 @
6a84872a
...
...
@@ -49,6 +49,7 @@
#include "board.h"
#include "sam9_smc.h"
#include "generic.h"
#include "gpio.h"
static
void
__init
ek_init_early
(
void
)
...
...
arch/arm/mach-at91/board-sam9261ek.c
浏览文件 @
6a84872a
...
...
@@ -53,6 +53,7 @@
#include "board.h"
#include "sam9_smc.h"
#include "generic.h"
#include "gpio.h"
static
void
__init
ek_init_early
(
void
)
...
...
arch/arm/mach-at91/board-sam9263ek.c
浏览文件 @
6a84872a
...
...
@@ -52,6 +52,7 @@
#include "board.h"
#include "sam9_smc.h"
#include "generic.h"
#include "gpio.h"
static
void
__init
ek_init_early
(
void
)
...
...
arch/arm/mach-at91/board-sam9g20ek.c
浏览文件 @
6a84872a
...
...
@@ -50,6 +50,7 @@
#include "board.h"
#include "sam9_smc.h"
#include "generic.h"
#include "gpio.h"
/*
* board revision encoding
...
...
arch/arm/mach-at91/board-sam9m10g45ek.c
浏览文件 @
6a84872a
...
...
@@ -50,6 +50,7 @@
#include "board.h"
#include "sam9_smc.h"
#include "generic.h"
#include "gpio.h"
static
void
__init
ek_init_early
(
void
)
...
...
@@ -300,21 +301,13 @@ static struct atmel_lcdfb_pdata __initdata ek_lcdc_data;
/*
* Touchscreen
*/
static
struct
at91_tsadcc_data
ek_tsadcc_data
=
{
.
adc_clock
=
300000
,
.
pendet_debounce
=
0x0d
,
.
ts_sample_hold_time
=
0x0a
,
};
/*
* ADCs
* ADCs and touchscreen
*/
static
struct
at91_adc_data
ek_adc_data
=
{
.
channels_used
=
BIT
(
0
)
|
BIT
(
1
)
|
BIT
(
2
)
|
BIT
(
3
)
|
BIT
(
4
)
|
BIT
(
5
)
|
BIT
(
6
)
|
BIT
(
7
),
.
use_external_triggers
=
true
,
.
vref
=
3300
,
.
touchscreen_type
=
ATMEL_ADC_TOUCHSCREEN_4WIRE
,
};
/*
...
...
@@ -485,9 +478,7 @@ static void __init ek_board_init(void)
at91_add_device_isi
(
&
isi_data
,
true
);
/* LCD Controller */
at91_add_device_lcdc
(
&
ek_lcdc_data
);
/* Touch Screen */
at91_add_device_tsadcc
(
&
ek_tsadcc_data
);
/* ADC */
/* ADC and touchscreen */
at91_add_device_adc
(
&
ek_adc_data
);
/* Push Buttons */
ek_add_device_buttons
();
...
...
arch/arm/mach-at91/board-sam9rlek.c
浏览文件 @
6a84872a
...
...
@@ -18,6 +18,7 @@
#include <linux/clk.h>
#include <linux/input.h>
#include <linux/gpio_keys.h>
#include <linux/platform_data/at91_adc.h>
#include <video/atmel_lcdc.h>
...
...
@@ -38,6 +39,7 @@
#include "board.h"
#include "sam9_smc.h"
#include "generic.h"
#include "gpio.h"
static
void
__init
ek_init_early
(
void
)
...
...
@@ -229,12 +231,13 @@ static struct gpio_led ek_leds[] = {
/*
* Touchscreen
*
ADC +
Touchscreen
*/
static
struct
at91_tsadcc_data
ek_tsadcc_data
=
{
.
adc_clock
=
1000000
,
.
pendet_debounce
=
0x0f
,
.
ts_sample_hold_time
=
0x03
,
static
struct
at91_adc_data
ek_adc_data
=
{
.
channels_used
=
BIT
(
0
)
|
BIT
(
1
)
|
BIT
(
2
)
|
BIT
(
3
)
|
BIT
(
4
)
|
BIT
(
5
),
.
use_external_triggers
=
true
,
.
vref
=
3300
,
.
touchscreen_type
=
ATMEL_ADC_TOUCHSCREEN_4WIRE
,
};
...
...
@@ -310,8 +313,8 @@ static void __init ek_board_init(void)
at91_add_device_lcdc
(
&
ek_lcdc_data
);
/* AC97 */
at91_add_device_ac97
(
&
ek_ac97_data
);
/* Touch Screen Controller */
at91_add_device_
tsadcc
(
&
ek_tsadc
c_data
);
/* Touch Screen Controller
+ ADC
*/
at91_add_device_
adc
(
&
ek_ad
c_data
);
/* LEDs */
at91_gpio_leds
(
ek_leds
,
ARRAY_SIZE
(
ek_leds
));
/* Push Buttons */
...
...
arch/arm/mach-at91/board-snapper9260.c
浏览文件 @
6a84872a
...
...
@@ -38,6 +38,7 @@
#include "board.h"
#include "sam9_smc.h"
#include "generic.h"
#include "gpio.h"
#define SNAPPER9260_IO_EXP_GPIO(x) (NR_BUILTIN_GPIO + (x))
...
...
arch/arm/mach-at91/board-stamp9g20.c
浏览文件 @
6a84872a
...
...
@@ -32,6 +32,7 @@
#include "board.h"
#include "sam9_smc.h"
#include "generic.h"
#include "gpio.h"
void
__init
stamp9g20_init_early
(
void
)
...
...
arch/arm/mach-at91/board-yl-9200.c
浏览文件 @
6a84872a
...
...
@@ -50,6 +50,7 @@
#include "at91_aic.h"
#include "board.h"
#include "generic.h"
#include "gpio.h"
static
void
__init
yl9200_init_early
(
void
)
...
...
arch/arm/mach-at91/board.h
浏览文件 @
6a84872a
...
...
@@ -118,9 +118,6 @@ struct isi_platform_data;
extern
void
__init
at91_add_device_isi
(
struct
isi_platform_data
*
data
,
bool
use_pck_as_mck
);
/* Touchscreen Controller */
extern
void
__init
at91_add_device_tsadcc
(
struct
at91_tsadcc_data
*
data
);
/* CAN */
extern
void
__init
at91_add_device_can
(
struct
at91_can_data
*
data
);
...
...
arch/arm/mach-at91/gpio.c
浏览文件 @
6a84872a
...
...
@@ -29,6 +29,7 @@
#include <mach/at91_pio.h>
#include "generic.h"
#include "gpio.h"
#define MAX_NB_GPIO_PER_BANK 32
...
...
arch/arm/mach-at91/
include/mach/
gpio.h
→
arch/arm/mach-at91/gpio.h
浏览文件 @
6a84872a
...
...
@@ -209,14 +209,6 @@ extern int at91_get_gpio_value(unsigned pin);
extern
void
at91_gpio_suspend
(
void
);
extern
void
at91_gpio_resume
(
void
);
#ifdef CONFIG_PINCTRL_AT91
extern
void
at91_pinctrl_gpio_suspend
(
void
);
extern
void
at91_pinctrl_gpio_resume
(
void
);
#else
static
inline
void
at91_pinctrl_gpio_suspend
(
void
)
{}
static
inline
void
at91_pinctrl_gpio_resume
(
void
)
{}
#endif
#endif
/* __ASSEMBLY__ */
#endif
arch/arm/mach-at91/include/mach/at91_adc.h
已删除
100644 → 0
浏览文件 @
d82b4013
/*
* arch/arm/mach-at91/include/mach/at91_adc.h
*
* Copyright (C) SAN People
*
* Analog-to-Digital Converter (ADC) registers.
* Based on AT91SAM9260 datasheet revision D.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#ifndef AT91_ADC_H
#define AT91_ADC_H
#define AT91_ADC_CR 0x00
/* Control Register */
#define AT91_ADC_SWRST (1 << 0)
/* Software Reset */
#define AT91_ADC_START (1 << 1)
/* Start Conversion */
#define AT91_ADC_MR 0x04
/* Mode Register */
#define AT91_ADC_TRGEN (1 << 0)
/* Trigger Enable */
#define AT91_ADC_TRGSEL (7 << 1)
/* Trigger Selection */
#define AT91_ADC_TRGSEL_TC0 (0 << 1)
#define AT91_ADC_TRGSEL_TC1 (1 << 1)
#define AT91_ADC_TRGSEL_TC2 (2 << 1)
#define AT91_ADC_TRGSEL_EXTERNAL (6 << 1)
#define AT91_ADC_LOWRES (1 << 4)
/* Low Resolution */
#define AT91_ADC_SLEEP (1 << 5)
/* Sleep Mode */
#define AT91_ADC_PRESCAL_9260 (0x3f << 8)
/* Prescalar Rate Selection */
#define AT91_ADC_PRESCAL_9G45 (0xff << 8)
#define AT91_ADC_PRESCAL_(x) ((x) << 8)
#define AT91_ADC_STARTUP_9260 (0x1f << 16)
/* Startup Up Time */
#define AT91_ADC_STARTUP_9G45 (0x7f << 16)
#define AT91_ADC_STARTUP_9X5 (0xf << 16)
#define AT91_ADC_STARTUP_(x) ((x) << 16)
#define AT91_ADC_SHTIM (0xf << 24)
/* Sample & Hold Time */
#define AT91_ADC_SHTIM_(x) ((x) << 24)
#define AT91_ADC_CHER 0x10
/* Channel Enable Register */
#define AT91_ADC_CHDR 0x14
/* Channel Disable Register */
#define AT91_ADC_CHSR 0x18
/* Channel Status Register */
#define AT91_ADC_CH(n) (1 << (n))
/* Channel Number */
#define AT91_ADC_SR 0x1C
/* Status Register */
#define AT91_ADC_EOC(n) (1 << (n))
/* End of Conversion on Channel N */
#define AT91_ADC_OVRE(n) (1 << ((n) + 8))
/* Overrun Error on Channel N */
#define AT91_ADC_DRDY (1 << 16)
/* Data Ready */
#define AT91_ADC_GOVRE (1 << 17)
/* General Overrun Error */
#define AT91_ADC_ENDRX (1 << 18)
/* End of RX Buffer */
#define AT91_ADC_RXFUFF (1 << 19)
/* RX Buffer Full */
#define AT91_ADC_SR_9X5 0x30
/* Status Register for 9x5 */
#define AT91_ADC_SR_DRDY_9X5 (1 << 24)
/* Data Ready */
#define AT91_ADC_LCDR 0x20
/* Last Converted Data Register */
#define AT91_ADC_LDATA (0x3ff)
#define AT91_ADC_IER 0x24
/* Interrupt Enable Register */
#define AT91_ADC_IDR 0x28
/* Interrupt Disable Register */
#define AT91_ADC_IMR 0x2C
/* Interrupt Mask Register */
#define AT91_ADC_IER_PEN (1 << 29)
#define AT91_ADC_IER_NOPEN (1 << 30)
#define AT91_ADC_IER_XRDY (1 << 20)
#define AT91_ADC_IER_YRDY (1 << 21)
#define AT91_ADC_IER_PRDY (1 << 22)
#define AT91_ADC_ISR_PENS (1 << 31)
#define AT91_ADC_CHR(n) (0x30 + ((n) * 4))
/* Channel Data Register N */
#define AT91_ADC_DATA (0x3ff)
#define AT91_ADC_CDR0_9X5 (0x50)
/* Channel Data Register 0 for 9X5 */
#define AT91_ADC_ACR 0x94
/* Analog Control Register */
#define AT91_ADC_ACR_PENDETSENS (0x3 << 0)
/* pull-up resistor */
#define AT91_ADC_TSMR 0xB0
#define AT91_ADC_TSMR_TSMODE (3 << 0)
/* Touch Screen Mode */
#define AT91_ADC_TSMR_TSMODE_NONE (0 << 0)
#define AT91_ADC_TSMR_TSMODE_4WIRE_NO_PRESS (1 << 0)
#define AT91_ADC_TSMR_TSMODE_4WIRE_PRESS (2 << 0)
#define AT91_ADC_TSMR_TSMODE_5WIRE (3 << 0)
#define AT91_ADC_TSMR_TSAV (3 << 4)
/* Averages samples */
#define AT91_ADC_TSMR_TSAV_(x) ((x) << 4)
#define AT91_ADC_TSMR_SCTIM (0x0f << 16)
/* Switch closure time */
#define AT91_ADC_TSMR_PENDBC (0x0f << 28)
/* Pen Debounce time */
#define AT91_ADC_TSMR_PENDBC_(x) ((x) << 28)
#define AT91_ADC_TSMR_NOTSDMA (1 << 22)
/* No Touchscreen DMA */
#define AT91_ADC_TSMR_PENDET_DIS (0 << 24)
/* Pen contact detection disable */
#define AT91_ADC_TSMR_PENDET_ENA (1 << 24)
/* Pen contact detection enable */
#define AT91_ADC_TSXPOSR 0xB4
#define AT91_ADC_TSYPOSR 0xB8
#define AT91_ADC_TSPRESSR 0xBC
#define AT91_ADC_TRGR_9260 AT91_ADC_MR
#define AT91_ADC_TRGR_9G45 0x08
#define AT91_ADC_TRGR_9X5 0xC0
/* Trigger Register bit field */
#define AT91_ADC_TRGR_TRGPER (0xffff << 16)
#define AT91_ADC_TRGR_TRGPER_(x) ((x) << 16)
#define AT91_ADC_TRGR_TRGMOD (0x7 << 0)
#define AT91_ADC_TRGR_MOD_PERIOD_TRIG (5 << 0)
#endif
arch/arm/mach-at91/include/mach/hardware.h
浏览文件 @
6a84872a
...
...
@@ -104,5 +104,20 @@
/* Clocks */
#define AT91_SLOW_CLOCK 32768
/* slow clock */
/*
* FIXME: this is needed to communicate between the pinctrl driver and
* the PM implementation in the machine. Possibly part of the PM
* implementation should be moved down into the pinctrl driver and get
* called as part of the generic suspend/resume path.
*/
#ifndef __ASSEMBLY__
#ifdef CONFIG_PINCTRL_AT91
extern
void
at91_pinctrl_gpio_suspend
(
void
);
extern
void
at91_pinctrl_gpio_resume
(
void
);
#else
static
inline
void
at91_pinctrl_gpio_suspend
(
void
)
{}
static
inline
void
at91_pinctrl_gpio_resume
(
void
)
{}
#endif
#endif
#endif
arch/arm/mach-at91/leds.c
浏览文件 @
6a84872a
...
...
@@ -16,6 +16,7 @@
#include <linux/platform_device.h>
#include "board.h"
#include "gpio.h"
/* ------------------------------------------------------------------------- */
...
...
arch/arm/mach-at91/pm.c
浏览文件 @
6a84872a
...
...
@@ -32,6 +32,7 @@
#include "at91_aic.h"
#include "generic.h"
#include "pm.h"
#include "gpio.h"
/*
* Show the reason for the previous system reset.
...
...
drivers/clk/at91/Makefile
浏览文件 @
6a84872a
...
...
@@ -2,8 +2,8 @@
# Makefile for at91 specific clk
#
obj-y
+=
pmc.o
obj-y
+=
clk-main.o clk-pll.o clk-plldiv.o clk-master.o
obj-y
+=
pmc.o
sckc.o
obj-y
+=
clk-
slow.o clk-
main.o clk-pll.o clk-plldiv.o clk-master.o
obj-y
+=
clk-system.o clk-peripheral.o clk-programmable.o
obj-$(CONFIG_HAVE_AT91_UTMI)
+=
clk-utmi.o
...
...
drivers/clk/at91/clk-main.c
浏览文件 @
6a84872a
...
...
@@ -30,99 +30,546 @@
#define MAINF_LOOP_MIN_WAIT (USEC_PER_SEC / SLOW_CLOCK_FREQ)
#define MAINF_LOOP_MAX_WAIT MAINFRDY_TIMEOUT
struct
clk_main
{
#define MOR_KEY_MASK (0xff << 16)
struct
clk_main_osc
{
struct
clk_hw
hw
;
struct
at91_pmc
*
pmc
;
unsigned
int
irq
;
wait_queue_head_t
wait
;
};
#define to_clk_main_osc(hw) container_of(hw, struct clk_main_osc, hw)
struct
clk_main_rc_osc
{
struct
clk_hw
hw
;
struct
at91_pmc
*
pmc
;
unsigned
int
irq
;
wait_queue_head_t
wait
;
unsigned
long
frequency
;
unsigned
long
accuracy
;
};
#define to_clk_main_rc_osc(hw) container_of(hw, struct clk_main_rc_osc, hw)
struct
clk_rm9200_main
{
struct
clk_hw
hw
;
struct
at91_pmc
*
pmc
;
};
#define to_clk_rm9200_main(hw) container_of(hw, struct clk_rm9200_main, hw)
struct
clk_sam9x5_main
{
struct
clk_hw
hw
;
struct
at91_pmc
*
pmc
;
unsigned
long
rate
;
unsigned
int
irq
;
wait_queue_head_t
wait
;
u8
parent
;
};
#define to_clk_
main(hw) container_of(hw, struct clk
_main, hw)
#define to_clk_
sam9x5_main(hw) container_of(hw, struct clk_sam9x5
_main, hw)
static
irqreturn_t
clk_main_irq_handler
(
int
irq
,
void
*
dev_id
)
static
irqreturn_t
clk_main_
osc_
irq_handler
(
int
irq
,
void
*
dev_id
)
{
struct
clk_main
*
clkmain
=
(
struct
clk_main
*
)
dev_id
;
struct
clk_main
_osc
*
osc
=
dev_id
;
wake_up
(
&
clkmain
->
wait
);
disable_irq_nosync
(
clkmain
->
irq
);
wake_up
(
&
osc
->
wait
);
disable_irq_nosync
(
osc
->
irq
);
return
IRQ_HANDLED
;
}
static
int
clk_main_prepare
(
struct
clk_hw
*
hw
)
static
int
clk_main_
osc_
prepare
(
struct
clk_hw
*
hw
)
{
struct
clk_main
*
clkmain
=
to_clk_main
(
hw
);
struct
at91_pmc
*
pmc
=
clkmain
->
pmc
;
unsigned
long
halt_time
,
timeout
;
struct
clk_main_osc
*
osc
=
to_clk_main_osc
(
hw
);
struct
at91_pmc
*
pmc
=
osc
->
pmc
;
u32
tmp
;
tmp
=
pmc_read
(
pmc
,
AT91_CKGR_MOR
)
&
~
MOR_KEY_MASK
;
if
(
tmp
&
AT91_PMC_OSCBYPASS
)
return
0
;
if
(
!
(
tmp
&
AT91_PMC_MOSCEN
))
{
tmp
|=
AT91_PMC_MOSCEN
|
AT91_PMC_KEY
;
pmc_write
(
pmc
,
AT91_CKGR_MOR
,
tmp
);
}
while
(
!
(
pmc_read
(
pmc
,
AT91_PMC_SR
)
&
AT91_PMC_MOSCS
))
{
enable_irq
(
clkmain
->
irq
);
wait_event
(
clkmain
->
wait
,
enable_irq
(
osc
->
irq
);
wait_event
(
osc
->
wait
,
pmc_read
(
pmc
,
AT91_PMC_SR
)
&
AT91_PMC_MOSCS
);
}
if
(
clkmain
->
rate
)
return
0
;
}
static
void
clk_main_osc_unprepare
(
struct
clk_hw
*
hw
)
{
struct
clk_main_osc
*
osc
=
to_clk_main_osc
(
hw
);
struct
at91_pmc
*
pmc
=
osc
->
pmc
;
u32
tmp
=
pmc_read
(
pmc
,
AT91_CKGR_MOR
);
if
(
tmp
&
AT91_PMC_OSCBYPASS
)
return
;
if
(
!
(
tmp
&
AT91_PMC_MOSCEN
))
return
;
tmp
&=
~
(
AT91_PMC_KEY
|
AT91_PMC_MOSCEN
);
pmc_write
(
pmc
,
AT91_CKGR_MOR
,
tmp
|
AT91_PMC_KEY
);
}
static
int
clk_main_osc_is_prepared
(
struct
clk_hw
*
hw
)
{
struct
clk_main_osc
*
osc
=
to_clk_main_osc
(
hw
);
struct
at91_pmc
*
pmc
=
osc
->
pmc
;
u32
tmp
=
pmc_read
(
pmc
,
AT91_CKGR_MOR
);
if
(
tmp
&
AT91_PMC_OSCBYPASS
)
return
1
;
return
!!
((
pmc_read
(
pmc
,
AT91_PMC_SR
)
&
AT91_PMC_MOSCS
)
&&
(
pmc_read
(
pmc
,
AT91_CKGR_MOR
)
&
AT91_PMC_MOSCEN
));
}
static
const
struct
clk_ops
main_osc_ops
=
{
.
prepare
=
clk_main_osc_prepare
,
.
unprepare
=
clk_main_osc_unprepare
,
.
is_prepared
=
clk_main_osc_is_prepared
,
};
static
struct
clk
*
__init
at91_clk_register_main_osc
(
struct
at91_pmc
*
pmc
,
unsigned
int
irq
,
const
char
*
name
,
const
char
*
parent_name
,
bool
bypass
)
{
int
ret
;
struct
clk_main_osc
*
osc
;
struct
clk
*
clk
=
NULL
;
struct
clk_init_data
init
;
if
(
!
pmc
||
!
irq
||
!
name
||
!
parent_name
)
return
ERR_PTR
(
-
EINVAL
);
osc
=
kzalloc
(
sizeof
(
*
osc
),
GFP_KERNEL
);
if
(
!
osc
)
return
ERR_PTR
(
-
ENOMEM
);
init
.
name
=
name
;
init
.
ops
=
&
main_osc_ops
;
init
.
parent_names
=
&
parent_name
;
init
.
num_parents
=
1
;
init
.
flags
=
CLK_IGNORE_UNUSED
;
osc
->
hw
.
init
=
&
init
;
osc
->
pmc
=
pmc
;
osc
->
irq
=
irq
;
init_waitqueue_head
(
&
osc
->
wait
);
irq_set_status_flags
(
osc
->
irq
,
IRQ_NOAUTOEN
);
ret
=
request_irq
(
osc
->
irq
,
clk_main_osc_irq_handler
,
IRQF_TRIGGER_HIGH
,
name
,
osc
);
if
(
ret
)
return
ERR_PTR
(
ret
);
if
(
bypass
)
pmc_write
(
pmc
,
AT91_CKGR_MOR
,
(
pmc_read
(
pmc
,
AT91_CKGR_MOR
)
&
~
(
MOR_KEY_MASK
|
AT91_PMC_MOSCEN
))
|
AT91_PMC_OSCBYPASS
|
AT91_PMC_KEY
);
clk
=
clk_register
(
NULL
,
&
osc
->
hw
);
if
(
IS_ERR
(
clk
))
{
free_irq
(
irq
,
osc
);
kfree
(
osc
);
}
return
clk
;
}
void
__init
of_at91rm9200_clk_main_osc_setup
(
struct
device_node
*
np
,
struct
at91_pmc
*
pmc
)
{
struct
clk
*
clk
;
unsigned
int
irq
;
const
char
*
name
=
np
->
name
;
const
char
*
parent_name
;
bool
bypass
;
of_property_read_string
(
np
,
"clock-output-names"
,
&
name
);
bypass
=
of_property_read_bool
(
np
,
"atmel,osc-bypass"
);
parent_name
=
of_clk_get_parent_name
(
np
,
0
);
irq
=
irq_of_parse_and_map
(
np
,
0
);
if
(
!
irq
)
return
;
clk
=
at91_clk_register_main_osc
(
pmc
,
irq
,
name
,
parent_name
,
bypass
);
if
(
IS_ERR
(
clk
))
return
;
of_clk_add_provider
(
np
,
of_clk_src_simple_get
,
clk
);
}
static
irqreturn_t
clk_main_rc_osc_irq_handler
(
int
irq
,
void
*
dev_id
)
{
struct
clk_main_rc_osc
*
osc
=
dev_id
;
wake_up
(
&
osc
->
wait
);
disable_irq_nosync
(
osc
->
irq
);
return
IRQ_HANDLED
;
}
static
int
clk_main_rc_osc_prepare
(
struct
clk_hw
*
hw
)
{
struct
clk_main_rc_osc
*
osc
=
to_clk_main_rc_osc
(
hw
);
struct
at91_pmc
*
pmc
=
osc
->
pmc
;
u32
tmp
;
tmp
=
pmc_read
(
pmc
,
AT91_CKGR_MOR
)
&
~
MOR_KEY_MASK
;
if
(
!
(
tmp
&
AT91_PMC_MOSCRCEN
))
{
tmp
|=
AT91_PMC_MOSCRCEN
|
AT91_PMC_KEY
;
pmc_write
(
pmc
,
AT91_CKGR_MOR
,
tmp
);
}
while
(
!
(
pmc_read
(
pmc
,
AT91_PMC_SR
)
&
AT91_PMC_MOSCRCS
))
{
enable_irq
(
osc
->
irq
);
wait_event
(
osc
->
wait
,
pmc_read
(
pmc
,
AT91_PMC_SR
)
&
AT91_PMC_MOSCRCS
);
}
return
0
;
}
static
void
clk_main_rc_osc_unprepare
(
struct
clk_hw
*
hw
)
{
struct
clk_main_rc_osc
*
osc
=
to_clk_main_rc_osc
(
hw
);
struct
at91_pmc
*
pmc
=
osc
->
pmc
;
u32
tmp
=
pmc_read
(
pmc
,
AT91_CKGR_MOR
);
if
(
!
(
tmp
&
AT91_PMC_MOSCRCEN
))
return
;
tmp
&=
~
(
MOR_KEY_MASK
|
AT91_PMC_MOSCRCEN
);
pmc_write
(
pmc
,
AT91_CKGR_MOR
,
tmp
|
AT91_PMC_KEY
);
}
static
int
clk_main_rc_osc_is_prepared
(
struct
clk_hw
*
hw
)
{
struct
clk_main_rc_osc
*
osc
=
to_clk_main_rc_osc
(
hw
);
struct
at91_pmc
*
pmc
=
osc
->
pmc
;
return
!!
((
pmc_read
(
pmc
,
AT91_PMC_SR
)
&
AT91_PMC_MOSCRCS
)
&&
(
pmc_read
(
pmc
,
AT91_CKGR_MOR
)
&
AT91_PMC_MOSCRCEN
));
}
static
unsigned
long
clk_main_rc_osc_recalc_rate
(
struct
clk_hw
*
hw
,
unsigned
long
parent_rate
)
{
struct
clk_main_rc_osc
*
osc
=
to_clk_main_rc_osc
(
hw
);
return
osc
->
frequency
;
}
static
unsigned
long
clk_main_rc_osc_recalc_accuracy
(
struct
clk_hw
*
hw
,
unsigned
long
parent_acc
)
{
struct
clk_main_rc_osc
*
osc
=
to_clk_main_rc_osc
(
hw
);
return
osc
->
accuracy
;
}
static
const
struct
clk_ops
main_rc_osc_ops
=
{
.
prepare
=
clk_main_rc_osc_prepare
,
.
unprepare
=
clk_main_rc_osc_unprepare
,
.
is_prepared
=
clk_main_rc_osc_is_prepared
,
.
recalc_rate
=
clk_main_rc_osc_recalc_rate
,
.
recalc_accuracy
=
clk_main_rc_osc_recalc_accuracy
,
};
static
struct
clk
*
__init
at91_clk_register_main_rc_osc
(
struct
at91_pmc
*
pmc
,
unsigned
int
irq
,
const
char
*
name
,
u32
frequency
,
u32
accuracy
)
{
int
ret
;
struct
clk_main_rc_osc
*
osc
;
struct
clk
*
clk
=
NULL
;
struct
clk_init_data
init
;
if
(
!
pmc
||
!
irq
||
!
name
||
!
frequency
)
return
ERR_PTR
(
-
EINVAL
);
osc
=
kzalloc
(
sizeof
(
*
osc
),
GFP_KERNEL
);
if
(
!
osc
)
return
ERR_PTR
(
-
ENOMEM
);
init
.
name
=
name
;
init
.
ops
=
&
main_rc_osc_ops
;
init
.
parent_names
=
NULL
;
init
.
num_parents
=
0
;
init
.
flags
=
CLK_IS_ROOT
|
CLK_IGNORE_UNUSED
;
osc
->
hw
.
init
=
&
init
;
osc
->
pmc
=
pmc
;
osc
->
irq
=
irq
;
osc
->
frequency
=
frequency
;
osc
->
accuracy
=
accuracy
;
init_waitqueue_head
(
&
osc
->
wait
);
irq_set_status_flags
(
osc
->
irq
,
IRQ_NOAUTOEN
);
ret
=
request_irq
(
osc
->
irq
,
clk_main_rc_osc_irq_handler
,
IRQF_TRIGGER_HIGH
,
name
,
osc
);
if
(
ret
)
return
ERR_PTR
(
ret
);
clk
=
clk_register
(
NULL
,
&
osc
->
hw
);
if
(
IS_ERR
(
clk
))
{
free_irq
(
irq
,
osc
);
kfree
(
osc
);
}
return
clk
;
}
void
__init
of_at91sam9x5_clk_main_rc_osc_setup
(
struct
device_node
*
np
,
struct
at91_pmc
*
pmc
)
{
struct
clk
*
clk
;
unsigned
int
irq
;
u32
frequency
=
0
;
u32
accuracy
=
0
;
const
char
*
name
=
np
->
name
;
of_property_read_string
(
np
,
"clock-output-names"
,
&
name
);
of_property_read_u32
(
np
,
"clock-frequency"
,
&
frequency
);
of_property_read_u32
(
np
,
"clock-accuracy"
,
&
accuracy
);
irq
=
irq_of_parse_and_map
(
np
,
0
);
if
(
!
irq
)
return
;
clk
=
at91_clk_register_main_rc_osc
(
pmc
,
irq
,
name
,
frequency
,
accuracy
);
if
(
IS_ERR
(
clk
))
return
;
of_clk_add_provider
(
np
,
of_clk_src_simple_get
,
clk
);
}
static
int
clk_main_probe_frequency
(
struct
at91_pmc
*
pmc
)
{
unsigned
long
prep_time
,
timeout
;
u32
tmp
;
timeout
=
jiffies
+
usecs_to_jiffies
(
MAINFRDY_TIMEOUT
);
do
{
halt
_time
=
jiffies
;
prep
_time
=
jiffies
;
tmp
=
pmc_read
(
pmc
,
AT91_CKGR_MCFR
);
if
(
tmp
&
AT91_PMC_MAINRDY
)
return
0
;
usleep_range
(
MAINF_LOOP_MIN_WAIT
,
MAINF_LOOP_MAX_WAIT
);
}
while
(
time_before
(
halt
_time
,
timeout
));
}
while
(
time_before
(
prep
_time
,
timeout
));
return
-
ETIMEDOUT
;
}
static
unsigned
long
clk_main_recalc_rate
(
struct
at91_pmc
*
pmc
,
unsigned
long
parent_rate
)
{
u32
tmp
;
if
(
parent_rate
)
return
parent_rate
;
tmp
=
pmc_read
(
pmc
,
AT91_CKGR_MCFR
);
if
(
!
(
tmp
&
AT91_PMC_MAINRDY
))
return
0
;
return
((
tmp
&
AT91_PMC_MAINF
)
*
SLOW_CLOCK_FREQ
)
/
MAINF_DIV
;
}
static
int
clk_
main_is_prepared
(
struct
clk_hw
*
hw
)
static
int
clk_
rm9200_main_prepare
(
struct
clk_hw
*
hw
)
{
struct
clk_
main
*
clkmain
=
to_clk
_main
(
hw
);
struct
clk_
rm9200_main
*
clkmain
=
to_clk_rm9200
_main
(
hw
);
return
!!
(
pmc_read
(
clkmain
->
pmc
,
AT91_PMC_SR
)
&
AT91_PMC_MOSCS
);
return
clk_main_probe_frequency
(
clkmain
->
pmc
);
}
static
unsigned
long
clk_main_recalc_rate
(
struct
clk_hw
*
hw
,
static
int
clk_rm9200_main_is_prepared
(
struct
clk_hw
*
hw
)
{
struct
clk_rm9200_main
*
clkmain
=
to_clk_rm9200_main
(
hw
);
return
!!
(
pmc_read
(
clkmain
->
pmc
,
AT91_CKGR_MCFR
)
&
AT91_PMC_MAINRDY
);
}
static
unsigned
long
clk_rm9200_main_recalc_rate
(
struct
clk_hw
*
hw
,
unsigned
long
parent_rate
)
{
u32
tmp
;
struct
clk_main
*
clkmain
=
to_clk_main
(
hw
);
struct
clk_rm9200_main
*
clkmain
=
to_clk_rm9200_main
(
hw
);
return
clk_main_recalc_rate
(
clkmain
->
pmc
,
parent_rate
);
}
static
const
struct
clk_ops
rm9200_main_ops
=
{
.
prepare
=
clk_rm9200_main_prepare
,
.
is_prepared
=
clk_rm9200_main_is_prepared
,
.
recalc_rate
=
clk_rm9200_main_recalc_rate
,
};
static
struct
clk
*
__init
at91_clk_register_rm9200_main
(
struct
at91_pmc
*
pmc
,
const
char
*
name
,
const
char
*
parent_name
)
{
struct
clk_rm9200_main
*
clkmain
;
struct
clk
*
clk
=
NULL
;
struct
clk_init_data
init
;
if
(
!
pmc
||
!
name
)
return
ERR_PTR
(
-
EINVAL
);
if
(
!
parent_name
)
return
ERR_PTR
(
-
EINVAL
);
clkmain
=
kzalloc
(
sizeof
(
*
clkmain
),
GFP_KERNEL
);
if
(
!
clkmain
)
return
ERR_PTR
(
-
ENOMEM
);
init
.
name
=
name
;
init
.
ops
=
&
rm9200_main_ops
;
init
.
parent_names
=
&
parent_name
;
init
.
num_parents
=
1
;
init
.
flags
=
0
;
clkmain
->
hw
.
init
=
&
init
;
clkmain
->
pmc
=
pmc
;
clk
=
clk_register
(
NULL
,
&
clkmain
->
hw
);
if
(
IS_ERR
(
clk
))
kfree
(
clkmain
);
return
clk
;
}
void
__init
of_at91rm9200_clk_main_setup
(
struct
device_node
*
np
,
struct
at91_pmc
*
pmc
)
{
struct
clk
*
clk
;
const
char
*
parent_name
;
const
char
*
name
=
np
->
name
;
parent_name
=
of_clk_get_parent_name
(
np
,
0
);
of_property_read_string
(
np
,
"clock-output-names"
,
&
name
);
clk
=
at91_clk_register_rm9200_main
(
pmc
,
name
,
parent_name
);
if
(
IS_ERR
(
clk
))
return
;
of_clk_add_provider
(
np
,
of_clk_src_simple_get
,
clk
);
}
static
irqreturn_t
clk_sam9x5_main_irq_handler
(
int
irq
,
void
*
dev_id
)
{
struct
clk_sam9x5_main
*
clkmain
=
dev_id
;
wake_up
(
&
clkmain
->
wait
);
disable_irq_nosync
(
clkmain
->
irq
);
return
IRQ_HANDLED
;
}
static
int
clk_sam9x5_main_prepare
(
struct
clk_hw
*
hw
)
{
struct
clk_sam9x5_main
*
clkmain
=
to_clk_sam9x5_main
(
hw
);
struct
at91_pmc
*
pmc
=
clkmain
->
pmc
;
if
(
clkmain
->
rate
)
return
clkmain
->
rate
;
while
(
!
(
pmc_read
(
pmc
,
AT91_PMC_SR
)
&
AT91_PMC_MOSCSELS
))
{
enable_irq
(
clkmain
->
irq
);
wait_event
(
clkmain
->
wait
,
pmc_read
(
pmc
,
AT91_PMC_SR
)
&
AT91_PMC_MOSCSELS
);
}
return
clk_main_probe_frequency
(
pmc
);
}
static
int
clk_sam9x5_main_is_prepared
(
struct
clk_hw
*
hw
)
{
struct
clk_sam9x5_main
*
clkmain
=
to_clk_sam9x5_main
(
hw
);
tmp
=
pmc_read
(
pmc
,
AT91_CKGR_MCFR
)
&
AT91_PMC_MAINF
;
clkmain
->
rate
=
(
tmp
*
parent_rate
)
/
MAINF_DIV
;
return
!!
(
pmc_read
(
clkmain
->
pmc
,
AT91_PMC_SR
)
&
AT91_PMC_MOSCSELS
);
}
static
unsigned
long
clk_sam9x5_main_recalc_rate
(
struct
clk_hw
*
hw
,
unsigned
long
parent_rate
)
{
struct
clk_sam9x5_main
*
clkmain
=
to_clk_sam9x5_main
(
hw
);
return
clk
main
->
rate
;
return
clk
_main_recalc_rate
(
clkmain
->
pmc
,
parent_rate
)
;
}
static
const
struct
clk_ops
main_ops
=
{
.
prepare
=
clk_main_prepare
,
.
is_prepared
=
clk_main_is_prepared
,
.
recalc_rate
=
clk_main_recalc_rate
,
static
int
clk_sam9x5_main_set_parent
(
struct
clk_hw
*
hw
,
u8
index
)
{
struct
clk_sam9x5_main
*
clkmain
=
to_clk_sam9x5_main
(
hw
);
struct
at91_pmc
*
pmc
=
clkmain
->
pmc
;
u32
tmp
;
if
(
index
>
1
)
return
-
EINVAL
;
tmp
=
pmc_read
(
pmc
,
AT91_CKGR_MOR
)
&
~
MOR_KEY_MASK
;
if
(
index
&&
!
(
tmp
&
AT91_PMC_MOSCSEL
))
pmc_write
(
pmc
,
AT91_CKGR_MOR
,
tmp
|
AT91_PMC_MOSCSEL
);
else
if
(
!
index
&&
(
tmp
&
AT91_PMC_MOSCSEL
))
pmc_write
(
pmc
,
AT91_CKGR_MOR
,
tmp
&
~
AT91_PMC_MOSCSEL
);
while
(
!
(
pmc_read
(
pmc
,
AT91_PMC_SR
)
&
AT91_PMC_MOSCSELS
))
{
enable_irq
(
clkmain
->
irq
);
wait_event
(
clkmain
->
wait
,
pmc_read
(
pmc
,
AT91_PMC_SR
)
&
AT91_PMC_MOSCSELS
);
}
return
0
;
}
static
u8
clk_sam9x5_main_get_parent
(
struct
clk_hw
*
hw
)
{
struct
clk_sam9x5_main
*
clkmain
=
to_clk_sam9x5_main
(
hw
);
return
!!
(
pmc_read
(
clkmain
->
pmc
,
AT91_CKGR_MOR
)
&
AT91_PMC_MOSCEN
);
}
static
const
struct
clk_ops
sam9x5_main_ops
=
{
.
prepare
=
clk_sam9x5_main_prepare
,
.
is_prepared
=
clk_sam9x5_main_is_prepared
,
.
recalc_rate
=
clk_sam9x5_main_recalc_rate
,
.
set_parent
=
clk_sam9x5_main_set_parent
,
.
get_parent
=
clk_sam9x5_main_get_parent
,
};
static
struct
clk
*
__init
at91_clk_register_main
(
struct
at91_pmc
*
pmc
,
at91_clk_register_
sam9x5_
main
(
struct
at91_pmc
*
pmc
,
unsigned
int
irq
,
const
char
*
name
,
const
char
*
parent_name
,
unsigned
long
rate
)
const
char
**
parent_names
,
int
num_parents
)
{
int
ret
;
struct
clk_main
*
clkmain
;
struct
clk_
sam9x5_
main
*
clkmain
;
struct
clk
*
clk
=
NULL
;
struct
clk_init_data
init
;
if
(
!
pmc
||
!
irq
||
!
name
)
return
ERR_PTR
(
-
EINVAL
);
if
(
!
rate
&&
!
parent_name
)
if
(
!
parent_names
||
!
num_parents
)
return
ERR_PTR
(
-
EINVAL
);
clkmain
=
kzalloc
(
sizeof
(
*
clkmain
),
GFP_KERNEL
);
...
...
@@ -130,19 +577,20 @@ at91_clk_register_main(struct at91_pmc *pmc,
return
ERR_PTR
(
-
ENOMEM
);
init
.
name
=
name
;
init
.
ops
=
&
main_ops
;
init
.
parent_names
=
parent_name
?
&
parent_name
:
NULL
;
init
.
num_parents
=
parent_name
?
1
:
0
;
init
.
flags
=
parent_name
?
0
:
CLK_IS_ROOT
;
init
.
ops
=
&
sam9x5_
main_ops
;
init
.
parent_names
=
parent_name
s
;
init
.
num_parents
=
num_parents
;
init
.
flags
=
CLK_SET_PARENT_GATE
;
clkmain
->
hw
.
init
=
&
init
;
clkmain
->
rate
=
rate
;
clkmain
->
pmc
=
pmc
;
clkmain
->
irq
=
irq
;
clkmain
->
parent
=
!!
(
pmc_read
(
clkmain
->
pmc
,
AT91_CKGR_MOR
)
&
AT91_PMC_MOSCEN
);
init_waitqueue_head
(
&
clkmain
->
wait
);
irq_set_status_flags
(
clkmain
->
irq
,
IRQ_NOAUTOEN
);
ret
=
request_irq
(
clkmain
->
irq
,
clk_main_irq_handler
,
IRQF_TRIGGER_HIGH
,
"clk-main"
,
clkmain
);
ret
=
request_irq
(
clkmain
->
irq
,
clk_
sam9x5_
main_irq_handler
,
IRQF_TRIGGER_HIGH
,
name
,
clkmain
);
if
(
ret
)
return
ERR_PTR
(
ret
);
...
...
@@ -155,33 +603,36 @@ at91_clk_register_main(struct at91_pmc *pmc,
return
clk
;
}
static
void
__init
of_at91_clk_main_setup
(
struct
device_node
*
np
,
struct
at91_pmc
*
pmc
)
void
__init
of_at91sam9x5_clk_main_setup
(
struct
device_node
*
np
,
struct
at91_pmc
*
pmc
)
{
struct
clk
*
clk
;
const
char
*
parent_names
[
2
];
int
num_parents
;
unsigned
int
irq
;
const
char
*
parent_name
;
const
char
*
name
=
np
->
name
;
u32
rate
=
0
;
int
i
;
num_parents
=
of_count_phandle_with_args
(
np
,
"clocks"
,
"#clock-cells"
);
if
(
num_parents
<=
0
||
num_parents
>
2
)
return
;
for
(
i
=
0
;
i
<
num_parents
;
++
i
)
{
parent_names
[
i
]
=
of_clk_get_parent_name
(
np
,
i
);
if
(
!
parent_names
[
i
])
return
;
}
parent_name
=
of_clk_get_parent_name
(
np
,
0
);
of_property_read_string
(
np
,
"clock-output-names"
,
&
name
);
of_property_read_u32
(
np
,
"clock-frequency"
,
&
rate
);
irq
=
irq_of_parse_and_map
(
np
,
0
);
if
(
!
irq
)
return
;
clk
=
at91_clk_register_main
(
pmc
,
irq
,
name
,
parent_name
,
rate
);
clk
=
at91_clk_register_sam9x5_main
(
pmc
,
irq
,
name
,
parent_names
,
num_parents
);
if
(
IS_ERR
(
clk
))
return
;
of_clk_add_provider
(
np
,
of_clk_src_simple_get
,
clk
);
}
void
__init
of_at91rm9200_clk_main_setup
(
struct
device_node
*
np
,
struct
at91_pmc
*
pmc
)
{
of_at91_clk_main_setup
(
np
,
pmc
);
}
drivers/clk/at91/clk-slow.c
0 → 100644
浏览文件 @
6a84872a
/*
* drivers/clk/at91/clk-slow.c
*
* Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
*/
#include <linux/clk-provider.h>
#include <linux/clkdev.h>
#include <linux/clk/at91_pmc.h>
#include <linux/delay.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/of_irq.h>
#include <linux/io.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
#include <linux/sched.h>
#include <linux/wait.h>
#include "pmc.h"
#include "sckc.h"
#define SLOW_CLOCK_FREQ 32768
#define SLOWCK_SW_CYCLES 5
#define SLOWCK_SW_TIME_USEC ((SLOWCK_SW_CYCLES * USEC_PER_SEC) / \
SLOW_CLOCK_FREQ)
#define AT91_SCKC_CR 0x00
#define AT91_SCKC_RCEN (1 << 0)
#define AT91_SCKC_OSC32EN (1 << 1)
#define AT91_SCKC_OSC32BYP (1 << 2)
#define AT91_SCKC_OSCSEL (1 << 3)
struct
clk_slow_osc
{
struct
clk_hw
hw
;
void
__iomem
*
sckcr
;
unsigned
long
startup_usec
;
};
#define to_clk_slow_osc(hw) container_of(hw, struct clk_slow_osc, hw)
struct
clk_slow_rc_osc
{
struct
clk_hw
hw
;
void
__iomem
*
sckcr
;
unsigned
long
frequency
;
unsigned
long
accuracy
;
unsigned
long
startup_usec
;
};
#define to_clk_slow_rc_osc(hw) container_of(hw, struct clk_slow_rc_osc, hw)
struct
clk_sam9260_slow
{
struct
clk_hw
hw
;
struct
at91_pmc
*
pmc
;
};
#define to_clk_sam9260_slow(hw) container_of(hw, struct clk_sam9260_slow, hw)
struct
clk_sam9x5_slow
{
struct
clk_hw
hw
;
void
__iomem
*
sckcr
;
u8
parent
;
};
#define to_clk_sam9x5_slow(hw) container_of(hw, struct clk_sam9x5_slow, hw)
static
int
clk_slow_osc_prepare
(
struct
clk_hw
*
hw
)
{
struct
clk_slow_osc
*
osc
=
to_clk_slow_osc
(
hw
);
void
__iomem
*
sckcr
=
osc
->
sckcr
;
u32
tmp
=
readl
(
sckcr
);
if
(
tmp
&
AT91_SCKC_OSC32BYP
)
return
0
;
writel
(
tmp
|
AT91_SCKC_OSC32EN
,
sckcr
);
usleep_range
(
osc
->
startup_usec
,
osc
->
startup_usec
+
1
);
return
0
;
}
static
void
clk_slow_osc_unprepare
(
struct
clk_hw
*
hw
)
{
struct
clk_slow_osc
*
osc
=
to_clk_slow_osc
(
hw
);
void
__iomem
*
sckcr
=
osc
->
sckcr
;
u32
tmp
=
readl
(
sckcr
);
if
(
tmp
&
AT91_SCKC_OSC32BYP
)
return
;
writel
(
tmp
&
~
AT91_SCKC_OSC32EN
,
sckcr
);
}
static
int
clk_slow_osc_is_prepared
(
struct
clk_hw
*
hw
)
{
struct
clk_slow_osc
*
osc
=
to_clk_slow_osc
(
hw
);
void
__iomem
*
sckcr
=
osc
->
sckcr
;
u32
tmp
=
readl
(
sckcr
);
if
(
tmp
&
AT91_SCKC_OSC32BYP
)
return
1
;
return
!!
(
tmp
&
AT91_SCKC_OSC32EN
);
}
static
const
struct
clk_ops
slow_osc_ops
=
{
.
prepare
=
clk_slow_osc_prepare
,
.
unprepare
=
clk_slow_osc_unprepare
,
.
is_prepared
=
clk_slow_osc_is_prepared
,
};
static
struct
clk
*
__init
at91_clk_register_slow_osc
(
void
__iomem
*
sckcr
,
const
char
*
name
,
const
char
*
parent_name
,
unsigned
long
startup
,
bool
bypass
)
{
struct
clk_slow_osc
*
osc
;
struct
clk
*
clk
=
NULL
;
struct
clk_init_data
init
;
if
(
!
sckcr
||
!
name
||
!
parent_name
)
return
ERR_PTR
(
-
EINVAL
);
osc
=
kzalloc
(
sizeof
(
*
osc
),
GFP_KERNEL
);
if
(
!
osc
)
return
ERR_PTR
(
-
ENOMEM
);
init
.
name
=
name
;
init
.
ops
=
&
slow_osc_ops
;
init
.
parent_names
=
&
parent_name
;
init
.
num_parents
=
1
;
init
.
flags
=
CLK_IGNORE_UNUSED
;
osc
->
hw
.
init
=
&
init
;
osc
->
sckcr
=
sckcr
;
osc
->
startup_usec
=
startup
;
if
(
bypass
)
writel
((
readl
(
sckcr
)
&
~
AT91_SCKC_OSC32EN
)
|
AT91_SCKC_OSC32BYP
,
sckcr
);
clk
=
clk_register
(
NULL
,
&
osc
->
hw
);
if
(
IS_ERR
(
clk
))
kfree
(
osc
);
return
clk
;
}
void
__init
of_at91sam9x5_clk_slow_osc_setup
(
struct
device_node
*
np
,
void
__iomem
*
sckcr
)
{
struct
clk
*
clk
;
const
char
*
parent_name
;
const
char
*
name
=
np
->
name
;
u32
startup
;
bool
bypass
;
parent_name
=
of_clk_get_parent_name
(
np
,
0
);
of_property_read_string
(
np
,
"clock-output-names"
,
&
name
);
of_property_read_u32
(
np
,
"atmel,startup-time-usec"
,
&
startup
);
bypass
=
of_property_read_bool
(
np
,
"atmel,osc-bypass"
);
clk
=
at91_clk_register_slow_osc
(
sckcr
,
name
,
parent_name
,
startup
,
bypass
);
if
(
IS_ERR
(
clk
))
return
;
of_clk_add_provider
(
np
,
of_clk_src_simple_get
,
clk
);
}
static
unsigned
long
clk_slow_rc_osc_recalc_rate
(
struct
clk_hw
*
hw
,
unsigned
long
parent_rate
)
{
struct
clk_slow_rc_osc
*
osc
=
to_clk_slow_rc_osc
(
hw
);
return
osc
->
frequency
;
}
static
unsigned
long
clk_slow_rc_osc_recalc_accuracy
(
struct
clk_hw
*
hw
,
unsigned
long
parent_acc
)
{
struct
clk_slow_rc_osc
*
osc
=
to_clk_slow_rc_osc
(
hw
);
return
osc
->
accuracy
;
}
static
int
clk_slow_rc_osc_prepare
(
struct
clk_hw
*
hw
)
{
struct
clk_slow_rc_osc
*
osc
=
to_clk_slow_rc_osc
(
hw
);
void
__iomem
*
sckcr
=
osc
->
sckcr
;
writel
(
readl
(
sckcr
)
|
AT91_SCKC_RCEN
,
sckcr
);
usleep_range
(
osc
->
startup_usec
,
osc
->
startup_usec
+
1
);
return
0
;
}
static
void
clk_slow_rc_osc_unprepare
(
struct
clk_hw
*
hw
)
{
struct
clk_slow_rc_osc
*
osc
=
to_clk_slow_rc_osc
(
hw
);
void
__iomem
*
sckcr
=
osc
->
sckcr
;
writel
(
readl
(
sckcr
)
&
~
AT91_SCKC_RCEN
,
sckcr
);
}
static
int
clk_slow_rc_osc_is_prepared
(
struct
clk_hw
*
hw
)
{
struct
clk_slow_rc_osc
*
osc
=
to_clk_slow_rc_osc
(
hw
);
return
!!
(
readl
(
osc
->
sckcr
)
&
AT91_SCKC_RCEN
);
}
static
const
struct
clk_ops
slow_rc_osc_ops
=
{
.
prepare
=
clk_slow_rc_osc_prepare
,
.
unprepare
=
clk_slow_rc_osc_unprepare
,
.
is_prepared
=
clk_slow_rc_osc_is_prepared
,
.
recalc_rate
=
clk_slow_rc_osc_recalc_rate
,
.
recalc_accuracy
=
clk_slow_rc_osc_recalc_accuracy
,
};
static
struct
clk
*
__init
at91_clk_register_slow_rc_osc
(
void
__iomem
*
sckcr
,
const
char
*
name
,
unsigned
long
frequency
,
unsigned
long
accuracy
,
unsigned
long
startup
)
{
struct
clk_slow_rc_osc
*
osc
;
struct
clk
*
clk
=
NULL
;
struct
clk_init_data
init
;
if
(
!
sckcr
||
!
name
)
return
ERR_PTR
(
-
EINVAL
);
osc
=
kzalloc
(
sizeof
(
*
osc
),
GFP_KERNEL
);
if
(
!
osc
)
return
ERR_PTR
(
-
ENOMEM
);
init
.
name
=
name
;
init
.
ops
=
&
slow_rc_osc_ops
;
init
.
parent_names
=
NULL
;
init
.
num_parents
=
0
;
init
.
flags
=
CLK_IS_ROOT
|
CLK_IGNORE_UNUSED
;
osc
->
hw
.
init
=
&
init
;
osc
->
sckcr
=
sckcr
;
osc
->
frequency
=
frequency
;
osc
->
accuracy
=
accuracy
;
osc
->
startup_usec
=
startup
;
clk
=
clk_register
(
NULL
,
&
osc
->
hw
);
if
(
IS_ERR
(
clk
))
kfree
(
osc
);
return
clk
;
}
void
__init
of_at91sam9x5_clk_slow_rc_osc_setup
(
struct
device_node
*
np
,
void
__iomem
*
sckcr
)
{
struct
clk
*
clk
;
u32
frequency
=
0
;
u32
accuracy
=
0
;
u32
startup
=
0
;
const
char
*
name
=
np
->
name
;
of_property_read_string
(
np
,
"clock-output-names"
,
&
name
);
of_property_read_u32
(
np
,
"clock-frequency"
,
&
frequency
);
of_property_read_u32
(
np
,
"clock-accuracy"
,
&
accuracy
);
of_property_read_u32
(
np
,
"atmel,startup-time-usec"
,
&
startup
);
clk
=
at91_clk_register_slow_rc_osc
(
sckcr
,
name
,
frequency
,
accuracy
,
startup
);
if
(
IS_ERR
(
clk
))
return
;
of_clk_add_provider
(
np
,
of_clk_src_simple_get
,
clk
);
}
static
int
clk_sam9x5_slow_set_parent
(
struct
clk_hw
*
hw
,
u8
index
)
{
struct
clk_sam9x5_slow
*
slowck
=
to_clk_sam9x5_slow
(
hw
);
void
__iomem
*
sckcr
=
slowck
->
sckcr
;
u32
tmp
;
if
(
index
>
1
)
return
-
EINVAL
;
tmp
=
readl
(
sckcr
);
if
((
!
index
&&
!
(
tmp
&
AT91_SCKC_OSCSEL
))
||
(
index
&&
(
tmp
&
AT91_SCKC_OSCSEL
)))
return
0
;
if
(
index
)
tmp
|=
AT91_SCKC_OSCSEL
;
else
tmp
&=
~
AT91_SCKC_OSCSEL
;
writel
(
tmp
,
sckcr
);
usleep_range
(
SLOWCK_SW_TIME_USEC
,
SLOWCK_SW_TIME_USEC
+
1
);
return
0
;
}
static
u8
clk_sam9x5_slow_get_parent
(
struct
clk_hw
*
hw
)
{
struct
clk_sam9x5_slow
*
slowck
=
to_clk_sam9x5_slow
(
hw
);
return
!!
(
readl
(
slowck
->
sckcr
)
&
AT91_SCKC_OSCSEL
);
}
static
const
struct
clk_ops
sam9x5_slow_ops
=
{
.
set_parent
=
clk_sam9x5_slow_set_parent
,
.
get_parent
=
clk_sam9x5_slow_get_parent
,
};
static
struct
clk
*
__init
at91_clk_register_sam9x5_slow
(
void
__iomem
*
sckcr
,
const
char
*
name
,
const
char
**
parent_names
,
int
num_parents
)
{
struct
clk_sam9x5_slow
*
slowck
;
struct
clk
*
clk
=
NULL
;
struct
clk_init_data
init
;
if
(
!
sckcr
||
!
name
||
!
parent_names
||
!
num_parents
)
return
ERR_PTR
(
-
EINVAL
);
slowck
=
kzalloc
(
sizeof
(
*
slowck
),
GFP_KERNEL
);
if
(
!
slowck
)
return
ERR_PTR
(
-
ENOMEM
);
init
.
name
=
name
;
init
.
ops
=
&
sam9x5_slow_ops
;
init
.
parent_names
=
parent_names
;
init
.
num_parents
=
num_parents
;
init
.
flags
=
0
;
slowck
->
hw
.
init
=
&
init
;
slowck
->
sckcr
=
sckcr
;
slowck
->
parent
=
!!
(
readl
(
sckcr
)
&
AT91_SCKC_OSCSEL
);
clk
=
clk_register
(
NULL
,
&
slowck
->
hw
);
if
(
IS_ERR
(
clk
))
kfree
(
slowck
);
return
clk
;
}
void
__init
of_at91sam9x5_clk_slow_setup
(
struct
device_node
*
np
,
void
__iomem
*
sckcr
)
{
struct
clk
*
clk
;
const
char
*
parent_names
[
2
];
int
num_parents
;
const
char
*
name
=
np
->
name
;
int
i
;
num_parents
=
of_count_phandle_with_args
(
np
,
"clocks"
,
"#clock-cells"
);
if
(
num_parents
<=
0
||
num_parents
>
2
)
return
;
for
(
i
=
0
;
i
<
num_parents
;
++
i
)
{
parent_names
[
i
]
=
of_clk_get_parent_name
(
np
,
i
);
if
(
!
parent_names
[
i
])
return
;
}
of_property_read_string
(
np
,
"clock-output-names"
,
&
name
);
clk
=
at91_clk_register_sam9x5_slow
(
sckcr
,
name
,
parent_names
,
num_parents
);
if
(
IS_ERR
(
clk
))
return
;
of_clk_add_provider
(
np
,
of_clk_src_simple_get
,
clk
);
}
static
u8
clk_sam9260_slow_get_parent
(
struct
clk_hw
*
hw
)
{
struct
clk_sam9260_slow
*
slowck
=
to_clk_sam9260_slow
(
hw
);
return
!!
(
pmc_read
(
slowck
->
pmc
,
AT91_PMC_SR
)
&
AT91_PMC_OSCSEL
);
}
static
const
struct
clk_ops
sam9260_slow_ops
=
{
.
get_parent
=
clk_sam9260_slow_get_parent
,
};
static
struct
clk
*
__init
at91_clk_register_sam9260_slow
(
struct
at91_pmc
*
pmc
,
const
char
*
name
,
const
char
**
parent_names
,
int
num_parents
)
{
struct
clk_sam9260_slow
*
slowck
;
struct
clk
*
clk
=
NULL
;
struct
clk_init_data
init
;
if
(
!
pmc
||
!
name
)
return
ERR_PTR
(
-
EINVAL
);
if
(
!
parent_names
||
!
num_parents
)
return
ERR_PTR
(
-
EINVAL
);
slowck
=
kzalloc
(
sizeof
(
*
slowck
),
GFP_KERNEL
);
if
(
!
slowck
)
return
ERR_PTR
(
-
ENOMEM
);
init
.
name
=
name
;
init
.
ops
=
&
sam9260_slow_ops
;
init
.
parent_names
=
parent_names
;
init
.
num_parents
=
num_parents
;
init
.
flags
=
0
;
slowck
->
hw
.
init
=
&
init
;
slowck
->
pmc
=
pmc
;
clk
=
clk_register
(
NULL
,
&
slowck
->
hw
);
if
(
IS_ERR
(
clk
))
kfree
(
slowck
);
return
clk
;
}
void
__init
of_at91sam9260_clk_slow_setup
(
struct
device_node
*
np
,
struct
at91_pmc
*
pmc
)
{
struct
clk
*
clk
;
const
char
*
parent_names
[
2
];
int
num_parents
;
const
char
*
name
=
np
->
name
;
int
i
;
num_parents
=
of_count_phandle_with_args
(
np
,
"clocks"
,
"#clock-cells"
);
if
(
num_parents
<=
0
||
num_parents
>
1
)
return
;
for
(
i
=
0
;
i
<
num_parents
;
++
i
)
{
parent_names
[
i
]
=
of_clk_get_parent_name
(
np
,
i
);
if
(
!
parent_names
[
i
])
return
;
}
of_property_read_string
(
np
,
"clock-output-names"
,
&
name
);
clk
=
at91_clk_register_sam9260_slow
(
pmc
,
name
,
parent_names
,
num_parents
);
if
(
IS_ERR
(
clk
))
return
;
of_clk_add_provider
(
np
,
of_clk_src_simple_get
,
clk
);
}
drivers/clk/at91/pmc.c
浏览文件 @
6a84872a
...
...
@@ -229,11 +229,28 @@ static struct at91_pmc *__init at91_pmc_init(struct device_node *np,
}
static
const
struct
of_device_id
pmc_clk_ids
[]
__initconst
=
{
/* Slow oscillator */
{
.
compatible
=
"atmel,at91sam9260-clk-slow"
,
.
data
=
of_at91sam9260_clk_slow_setup
,
},
/* Main clock */
{
.
compatible
=
"atmel,at91rm9200-clk-main-osc"
,
.
data
=
of_at91rm9200_clk_main_osc_setup
,
},
{
.
compatible
=
"atmel,at91sam9x5-clk-main-rc-osc"
,
.
data
=
of_at91sam9x5_clk_main_rc_osc_setup
,
},
{
.
compatible
=
"atmel,at91rm9200-clk-main"
,
.
data
=
of_at91rm9200_clk_main_setup
,
},
{
.
compatible
=
"atmel,at91sam9x5-clk-main"
,
.
data
=
of_at91sam9x5_clk_main_setup
,
},
/* PLL clocks */
{
.
compatible
=
"atmel,at91rm9200-clk-pll"
,
...
...
drivers/clk/at91/pmc.h
浏览文件 @
6a84872a
...
...
@@ -58,8 +58,17 @@ static inline void pmc_write(struct at91_pmc *pmc, int offset, u32 value)
int
of_at91_get_clk_range
(
struct
device_node
*
np
,
const
char
*
propname
,
struct
clk_range
*
range
);
extern
void
__init
of_at91sam9260_clk_slow_setup
(
struct
device_node
*
np
,
struct
at91_pmc
*
pmc
);
extern
void
__init
of_at91rm9200_clk_main_osc_setup
(
struct
device_node
*
np
,
struct
at91_pmc
*
pmc
);
extern
void
__init
of_at91sam9x5_clk_main_rc_osc_setup
(
struct
device_node
*
np
,
struct
at91_pmc
*
pmc
);
extern
void
__init
of_at91rm9200_clk_main_setup
(
struct
device_node
*
np
,
struct
at91_pmc
*
pmc
);
extern
void
__init
of_at91sam9x5_clk_main_setup
(
struct
device_node
*
np
,
struct
at91_pmc
*
pmc
);
extern
void
__init
of_at91rm9200_clk_pll_setup
(
struct
device_node
*
np
,
struct
at91_pmc
*
pmc
);
...
...
drivers/clk/at91/sckc.c
0 → 100644
浏览文件 @
6a84872a
/*
* drivers/clk/at91/sckc.c
*
* Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
*/
#include <linux/clk-provider.h>
#include <linux/clkdev.h>
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/io.h>
#include "sckc.h"
static
const
struct
of_device_id
sckc_clk_ids
[]
__initconst
=
{
/* Slow clock */
{
.
compatible
=
"atmel,at91sam9x5-clk-slow-osc"
,
.
data
=
of_at91sam9x5_clk_slow_osc_setup
,
},
{
.
compatible
=
"atmel,at91sam9x5-clk-slow-rc-osc"
,
.
data
=
of_at91sam9x5_clk_slow_rc_osc_setup
,
},
{
.
compatible
=
"atmel,at91sam9x5-clk-slow"
,
.
data
=
of_at91sam9x5_clk_slow_setup
,
},
{
/*sentinel*/
}
};
static
void
__init
of_at91sam9x5_sckc_setup
(
struct
device_node
*
np
)
{
struct
device_node
*
childnp
;
void
(
*
clk_setup
)(
struct
device_node
*
,
void
__iomem
*
);
const
struct
of_device_id
*
clk_id
;
void
__iomem
*
regbase
=
of_iomap
(
np
,
0
);
if
(
!
regbase
)
return
;
for_each_child_of_node
(
np
,
childnp
)
{
clk_id
=
of_match_node
(
sckc_clk_ids
,
childnp
);
if
(
!
clk_id
)
continue
;
clk_setup
=
clk_id
->
data
;
clk_setup
(
childnp
,
regbase
);
}
}
CLK_OF_DECLARE
(
at91sam9x5_clk_sckc
,
"atmel,at91sam9x5-sckc"
,
of_at91sam9x5_sckc_setup
);
drivers/clk/at91/sckc.h
0 → 100644
浏览文件 @
6a84872a
/*
* drivers/clk/at91/sckc.h
*
* Copyright (C) 2013 Boris BREZILLON <b.brezillon@overkiz.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*/
#ifndef __AT91_SCKC_H_
#define __AT91_SCKC_H_
extern
void
__init
of_at91sam9x5_clk_slow_osc_setup
(
struct
device_node
*
np
,
void
__iomem
*
sckcr
);
extern
void
__init
of_at91sam9x5_clk_slow_rc_osc_setup
(
struct
device_node
*
np
,
void
__iomem
*
sckcr
);
extern
void
__init
of_at91sam9x5_clk_slow_setup
(
struct
device_node
*
np
,
void
__iomem
*
sckcr
);
#endif
/* __AT91_SCKC_H_ */
drivers/iio/adc/at91_adc.c
浏览文件 @
6a84872a
...
...
@@ -31,7 +31,108 @@
#include <linux/iio/trigger_consumer.h>
#include <linux/iio/triggered_buffer.h>
#include <mach/at91_adc.h>
/* Registers */
#define AT91_ADC_CR 0x00
/* Control Register */
#define AT91_ADC_SWRST (1 << 0)
/* Software Reset */
#define AT91_ADC_START (1 << 1)
/* Start Conversion */
#define AT91_ADC_MR 0x04
/* Mode Register */
#define AT91_ADC_TSAMOD (3 << 0)
/* ADC mode */
#define AT91_ADC_TSAMOD_ADC_ONLY_MODE (0 << 0)
/* ADC Mode */
#define AT91_ADC_TSAMOD_TS_ONLY_MODE (1 << 0)
/* Touch Screen Only Mode */
#define AT91_ADC_TRGEN (1 << 0)
/* Trigger Enable */
#define AT91_ADC_TRGSEL (7 << 1)
/* Trigger Selection */
#define AT91_ADC_TRGSEL_TC0 (0 << 1)
#define AT91_ADC_TRGSEL_TC1 (1 << 1)
#define AT91_ADC_TRGSEL_TC2 (2 << 1)
#define AT91_ADC_TRGSEL_EXTERNAL (6 << 1)
#define AT91_ADC_LOWRES (1 << 4)
/* Low Resolution */
#define AT91_ADC_SLEEP (1 << 5)
/* Sleep Mode */
#define AT91_ADC_PENDET (1 << 6)
/* Pen contact detection enable */
#define AT91_ADC_PRESCAL_9260 (0x3f << 8)
/* Prescalar Rate Selection */
#define AT91_ADC_PRESCAL_9G45 (0xff << 8)
#define AT91_ADC_PRESCAL_(x) ((x) << 8)
#define AT91_ADC_STARTUP_9260 (0x1f << 16)
/* Startup Up Time */
#define AT91_ADC_STARTUP_9G45 (0x7f << 16)
#define AT91_ADC_STARTUP_9X5 (0xf << 16)
#define AT91_ADC_STARTUP_(x) ((x) << 16)
#define AT91_ADC_SHTIM (0xf << 24)
/* Sample & Hold Time */
#define AT91_ADC_SHTIM_(x) ((x) << 24)
#define AT91_ADC_PENDBC (0x0f << 28)
/* Pen Debounce time */
#define AT91_ADC_PENDBC_(x) ((x) << 28)
#define AT91_ADC_TSR 0x0C
#define AT91_ADC_TSR_SHTIM (0xf << 24)
/* Sample & Hold Time */
#define AT91_ADC_TSR_SHTIM_(x) ((x) << 24)
#define AT91_ADC_CHER 0x10
/* Channel Enable Register */
#define AT91_ADC_CHDR 0x14
/* Channel Disable Register */
#define AT91_ADC_CHSR 0x18
/* Channel Status Register */
#define AT91_ADC_CH(n) (1 << (n))
/* Channel Number */
#define AT91_ADC_SR 0x1C
/* Status Register */
#define AT91_ADC_EOC(n) (1 << (n))
/* End of Conversion on Channel N */
#define AT91_ADC_OVRE(n) (1 << ((n) + 8))
/* Overrun Error on Channel N */
#define AT91_ADC_DRDY (1 << 16)
/* Data Ready */
#define AT91_ADC_GOVRE (1 << 17)
/* General Overrun Error */
#define AT91_ADC_ENDRX (1 << 18)
/* End of RX Buffer */
#define AT91_ADC_RXFUFF (1 << 19)
/* RX Buffer Full */
#define AT91_ADC_SR_9X5 0x30
/* Status Register for 9x5 */
#define AT91_ADC_SR_DRDY_9X5 (1 << 24)
/* Data Ready */
#define AT91_ADC_LCDR 0x20
/* Last Converted Data Register */
#define AT91_ADC_LDATA (0x3ff)
#define AT91_ADC_IER 0x24
/* Interrupt Enable Register */
#define AT91_ADC_IDR 0x28
/* Interrupt Disable Register */
#define AT91_ADC_IMR 0x2C
/* Interrupt Mask Register */
#define AT91RL_ADC_IER_PEN (1 << 20)
#define AT91RL_ADC_IER_NOPEN (1 << 21)
#define AT91_ADC_IER_PEN (1 << 29)
#define AT91_ADC_IER_NOPEN (1 << 30)
#define AT91_ADC_IER_XRDY (1 << 20)
#define AT91_ADC_IER_YRDY (1 << 21)
#define AT91_ADC_IER_PRDY (1 << 22)
#define AT91_ADC_ISR_PENS (1 << 31)
#define AT91_ADC_CHR(n) (0x30 + ((n) * 4))
/* Channel Data Register N */
#define AT91_ADC_DATA (0x3ff)
#define AT91_ADC_CDR0_9X5 (0x50)
/* Channel Data Register 0 for 9X5 */
#define AT91_ADC_ACR 0x94
/* Analog Control Register */
#define AT91_ADC_ACR_PENDETSENS (0x3 << 0)
/* pull-up resistor */
#define AT91_ADC_TSMR 0xB0
#define AT91_ADC_TSMR_TSMODE (3 << 0)
/* Touch Screen Mode */
#define AT91_ADC_TSMR_TSMODE_NONE (0 << 0)
#define AT91_ADC_TSMR_TSMODE_4WIRE_NO_PRESS (1 << 0)
#define AT91_ADC_TSMR_TSMODE_4WIRE_PRESS (2 << 0)
#define AT91_ADC_TSMR_TSMODE_5WIRE (3 << 0)
#define AT91_ADC_TSMR_TSAV (3 << 4)
/* Averages samples */
#define AT91_ADC_TSMR_TSAV_(x) ((x) << 4)
#define AT91_ADC_TSMR_SCTIM (0x0f << 16)
/* Switch closure time */
#define AT91_ADC_TSMR_PENDBC (0x0f << 28)
/* Pen Debounce time */
#define AT91_ADC_TSMR_PENDBC_(x) ((x) << 28)
#define AT91_ADC_TSMR_NOTSDMA (1 << 22)
/* No Touchscreen DMA */
#define AT91_ADC_TSMR_PENDET_DIS (0 << 24)
/* Pen contact detection disable */
#define AT91_ADC_TSMR_PENDET_ENA (1 << 24)
/* Pen contact detection enable */
#define AT91_ADC_TSXPOSR 0xB4
#define AT91_ADC_TSYPOSR 0xB8
#define AT91_ADC_TSPRESSR 0xBC
#define AT91_ADC_TRGR_9260 AT91_ADC_MR
#define AT91_ADC_TRGR_9G45 0x08
#define AT91_ADC_TRGR_9X5 0xC0
/* Trigger Register bit field */
#define AT91_ADC_TRGR_TRGPER (0xffff << 16)
#define AT91_ADC_TRGR_TRGPER_(x) ((x) << 16)
#define AT91_ADC_TRGR_TRGMOD (0x7 << 0)
#define AT91_ADC_TRGR_NONE (0 << 0)
#define AT91_ADC_TRGR_MOD_PERIOD_TRIG (5 << 0)
#define AT91_ADC_CHAN(st, ch) \
(st->registers->channel_base + (ch * 4))
...
...
@@ -46,6 +147,29 @@
#define TOUCH_SAMPLE_PERIOD_US 2000
/* 2ms */
#define TOUCH_PEN_DETECT_DEBOUNCE_US 200
#define MAX_RLPOS_BITS 10
#define TOUCH_SAMPLE_PERIOD_US_RL 10000
/* 10ms, the SoC can't keep up with 2ms */
#define TOUCH_SHTIM 0xa
/**
* struct at91_adc_reg_desc - Various informations relative to registers
* @channel_base: Base offset for the channel data registers
* @drdy_mask: Mask of the DRDY field in the relevant registers
(Interruptions registers mostly)
* @status_register: Offset of the Interrupt Status Register
* @trigger_register: Offset of the Trigger setup register
* @mr_prescal_mask: Mask of the PRESCAL field in the adc MR register
* @mr_startup_mask: Mask of the STARTUP field in the adc MR register
*/
struct
at91_adc_reg_desc
{
u8
channel_base
;
u32
drdy_mask
;
u8
status_register
;
u8
trigger_register
;
u32
mr_prescal_mask
;
u32
mr_startup_mask
;
};
struct
at91_adc_caps
{
bool
has_ts
;
/* Support touch screen */
bool
has_tsmr
;
/* only at91sam9x5, sama5d3 have TSMR reg */
...
...
@@ -64,12 +188,6 @@ struct at91_adc_caps {
struct
at91_adc_reg_desc
registers
;
};
enum
atmel_adc_ts_type
{
ATMEL_ADC_TOUCHSCREEN_NONE
=
0
,
ATMEL_ADC_TOUCHSCREEN_4WIRE
=
4
,
ATMEL_ADC_TOUCHSCREEN_5WIRE
=
5
,
};
struct
at91_adc_state
{
struct
clk
*
adc_clk
;
u16
*
buffer
;
...
...
@@ -114,6 +232,11 @@ struct at91_adc_state {
u16
ts_sample_period_val
;
u32
ts_pressure_threshold
;
u16
ts_pendbc
;
bool
ts_bufferedmeasure
;
u32
ts_prev_absx
;
u32
ts_prev_absy
;
};
static
irqreturn_t
at91_adc_trigger_handler
(
int
irq
,
void
*
p
)
...
...
@@ -220,7 +343,72 @@ static int at91_ts_sample(struct at91_adc_state *st)
return
0
;
}
static
irqreturn_t
at91_adc_interrupt
(
int
irq
,
void
*
private
)
static
irqreturn_t
at91_adc_rl_interrupt
(
int
irq
,
void
*
private
)
{
struct
iio_dev
*
idev
=
private
;
struct
at91_adc_state
*
st
=
iio_priv
(
idev
);
u32
status
=
at91_adc_readl
(
st
,
st
->
registers
->
status_register
);
unsigned
int
reg
;
status
&=
at91_adc_readl
(
st
,
AT91_ADC_IMR
);
if
(
status
&
st
->
registers
->
drdy_mask
)
handle_adc_eoc_trigger
(
irq
,
idev
);
if
(
status
&
AT91RL_ADC_IER_PEN
)
{
/* Disabling pen debounce is required to get a NOPEN irq */
reg
=
at91_adc_readl
(
st
,
AT91_ADC_MR
);
reg
&=
~
AT91_ADC_PENDBC
;
at91_adc_writel
(
st
,
AT91_ADC_MR
,
reg
);
at91_adc_writel
(
st
,
AT91_ADC_IDR
,
AT91RL_ADC_IER_PEN
);
at91_adc_writel
(
st
,
AT91_ADC_IER
,
AT91RL_ADC_IER_NOPEN
|
AT91_ADC_EOC
(
3
));
/* Set up period trigger for sampling */
at91_adc_writel
(
st
,
st
->
registers
->
trigger_register
,
AT91_ADC_TRGR_MOD_PERIOD_TRIG
|
AT91_ADC_TRGR_TRGPER_
(
st
->
ts_sample_period_val
));
}
else
if
(
status
&
AT91RL_ADC_IER_NOPEN
)
{
reg
=
at91_adc_readl
(
st
,
AT91_ADC_MR
);
reg
|=
AT91_ADC_PENDBC_
(
st
->
ts_pendbc
)
&
AT91_ADC_PENDBC
;
at91_adc_writel
(
st
,
AT91_ADC_MR
,
reg
);
at91_adc_writel
(
st
,
st
->
registers
->
trigger_register
,
AT91_ADC_TRGR_NONE
);
at91_adc_writel
(
st
,
AT91_ADC_IDR
,
AT91RL_ADC_IER_NOPEN
|
AT91_ADC_EOC
(
3
));
at91_adc_writel
(
st
,
AT91_ADC_IER
,
AT91RL_ADC_IER_PEN
);
st
->
ts_bufferedmeasure
=
false
;
input_report_key
(
st
->
ts_input
,
BTN_TOUCH
,
0
);
input_sync
(
st
->
ts_input
);
}
else
if
(
status
&
AT91_ADC_EOC
(
3
))
{
/* Conversion finished */
if
(
st
->
ts_bufferedmeasure
)
{
/*
* Last measurement is always discarded, since it can
* be erroneous.
* Always report previous measurement
*/
input_report_abs
(
st
->
ts_input
,
ABS_X
,
st
->
ts_prev_absx
);
input_report_abs
(
st
->
ts_input
,
ABS_Y
,
st
->
ts_prev_absy
);
input_report_key
(
st
->
ts_input
,
BTN_TOUCH
,
1
);
input_sync
(
st
->
ts_input
);
}
else
st
->
ts_bufferedmeasure
=
true
;
/* Now make new measurement */
st
->
ts_prev_absx
=
at91_adc_readl
(
st
,
AT91_ADC_CHAN
(
st
,
3
))
<<
MAX_RLPOS_BITS
;
st
->
ts_prev_absx
/=
at91_adc_readl
(
st
,
AT91_ADC_CHAN
(
st
,
2
));
st
->
ts_prev_absy
=
at91_adc_readl
(
st
,
AT91_ADC_CHAN
(
st
,
1
))
<<
MAX_RLPOS_BITS
;
st
->
ts_prev_absy
/=
at91_adc_readl
(
st
,
AT91_ADC_CHAN
(
st
,
0
));
}
return
IRQ_HANDLED
;
}
static
irqreturn_t
at91_adc_9x5_interrupt
(
int
irq
,
void
*
private
)
{
struct
iio_dev
*
idev
=
private
;
struct
at91_adc_state
*
st
=
iio_priv
(
idev
);
...
...
@@ -653,6 +841,8 @@ static int at91_adc_probe_dt_ts(struct device_node *node,
return
-
EINVAL
;
}
if
(
!
st
->
caps
->
has_tsmr
)
return
0
;
prop
=
0
;
of_property_read_u32
(
node
,
"atmel,adc-ts-pressure-threshold"
,
&
prop
);
st
->
ts_pressure_threshold
=
prop
;
...
...
@@ -776,6 +966,7 @@ static int at91_adc_probe_pdata(struct at91_adc_state *st,
st
->
trigger_number
=
pdata
->
trigger_number
;
st
->
trigger_list
=
pdata
->
trigger_list
;
st
->
registers
=
&
st
->
caps
->
registers
;
st
->
touchscreen_type
=
pdata
->
touchscreen_type
;
return
0
;
}
...
...
@@ -790,7 +981,10 @@ static int atmel_ts_open(struct input_dev *dev)
{
struct
at91_adc_state
*
st
=
input_get_drvdata
(
dev
);
if
(
st
->
caps
->
has_tsmr
)
at91_adc_writel
(
st
,
AT91_ADC_IER
,
AT91_ADC_IER_PEN
);
else
at91_adc_writel
(
st
,
AT91_ADC_IER
,
AT91RL_ADC_IER_PEN
);
return
0
;
}
...
...
@@ -798,44 +992,60 @@ static void atmel_ts_close(struct input_dev *dev)
{
struct
at91_adc_state
*
st
=
input_get_drvdata
(
dev
);
if
(
st
->
caps
->
has_tsmr
)
at91_adc_writel
(
st
,
AT91_ADC_IDR
,
AT91_ADC_IER_PEN
);
else
at91_adc_writel
(
st
,
AT91_ADC_IDR
,
AT91RL_ADC_IER_PEN
);
}
static
int
at91_ts_hw_init
(
struct
at91_adc_state
*
st
,
u32
adc_clk_khz
)
{
u32
reg
=
0
,
pendbc
;
u32
reg
=
0
;
int
i
=
0
;
if
(
st
->
touchscreen_type
==
ATMEL_ADC_TOUCHSCREEN_4WIRE
)
reg
=
AT91_ADC_TSMR_TSMODE_4WIRE_PRESS
;
else
reg
=
AT91_ADC_TSMR_TSMODE_5WIRE
;
/* a Pen Detect Debounce Time is necessary for the ADC Touch to avoid
* pen detect noise.
* The formula is : Pen Detect Debounce Time = (2 ^ pendbc) / ADCClock
*/
pendbc
=
round_up
(
TOUCH_PEN_DETECT_DEBOUNCE_US
*
adc_clk_khz
/
1000
,
1
);
st
->
ts_pendbc
=
round_up
(
TOUCH_PEN_DETECT_DEBOUNCE_US
*
adc_clk_khz
/
1000
,
1
);
while
(
pendbc
>>
++
i
)
while
(
st
->
ts_
pendbc
>>
++
i
)
;
/* Empty! Find the shift offset */
if
(
abs
(
pendbc
-
(
1
<<
i
))
<
abs
(
pendbc
-
(
1
<<
(
i
-
1
))))
pendbc
=
i
;
if
(
abs
(
st
->
ts_pendbc
-
(
1
<<
i
))
<
abs
(
st
->
ts_
pendbc
-
(
1
<<
(
i
-
1
))))
st
->
ts_
pendbc
=
i
;
else
pendbc
=
i
-
1
;
st
->
ts_pendbc
=
i
-
1
;
if
(
!
st
->
caps
->
has_tsmr
)
{
reg
=
at91_adc_readl
(
st
,
AT91_ADC_MR
);
reg
|=
AT91_ADC_TSAMOD_TS_ONLY_MODE
|
AT91_ADC_PENDET
;
reg
|=
AT91_ADC_PENDBC_
(
st
->
ts_pendbc
)
&
AT91_ADC_PENDBC
;
at91_adc_writel
(
st
,
AT91_ADC_MR
,
reg
);
reg
=
AT91_ADC_TSR_SHTIM_
(
TOUCH_SHTIM
)
&
AT91_ADC_TSR_SHTIM
;
at91_adc_writel
(
st
,
AT91_ADC_TSR
,
reg
);
st
->
ts_sample_period_val
=
round_up
((
TOUCH_SAMPLE_PERIOD_US_RL
*
adc_clk_khz
/
1000
)
-
1
,
1
);
return
0
;
}
if
(
st
->
touchscreen_type
==
ATMEL_ADC_TOUCHSCREEN_4WIRE
)
reg
=
AT91_ADC_TSMR_TSMODE_4WIRE_PRESS
;
else
reg
=
AT91_ADC_TSMR_TSMODE_5WIRE
;
if
(
st
->
caps
->
has_tsmr
)
{
reg
|=
AT91_ADC_TSMR_TSAV_
(
st
->
caps
->
ts_filter_average
)
&
AT91_ADC_TSMR_TSAV
;
reg
|=
AT91_ADC_TSMR_PENDBC_
(
pendbc
)
&
AT91_ADC_TSMR_PENDBC
;
reg
|=
AT91_ADC_TSMR_PENDBC_
(
st
->
ts_
pendbc
)
&
AT91_ADC_TSMR_PENDBC
;
reg
|=
AT91_ADC_TSMR_NOTSDMA
;
reg
|=
AT91_ADC_TSMR_PENDET_ENA
;
reg
|=
0x03
<<
8
;
/* TSFREQ, need
bigger than TSAV */
reg
|=
0x03
<<
8
;
/* TSFREQ, needs to be
bigger than TSAV */
at91_adc_writel
(
st
,
AT91_ADC_TSMR
,
reg
);
}
else
{
/* TODO: for 9g45 which has no TSMR */
}
/* Change adc internal resistor value for better pen detection,
* default value is 100 kOhm.
...
...
@@ -845,7 +1055,7 @@ static int at91_ts_hw_init(struct at91_adc_state *st, u32 adc_clk_khz)
at91_adc_writel
(
st
,
AT91_ADC_ACR
,
st
->
caps
->
ts_pen_detect_sensitivity
&
AT91_ADC_ACR_PENDETSENS
);
/* Sample Per
oi
d Time = (TRGPER + 1) / ADCClock */
/* Sample Per
io
d Time = (TRGPER + 1) / ADCClock */
st
->
ts_sample_period_val
=
round_up
((
TOUCH_SAMPLE_PERIOD_US
*
adc_clk_khz
/
1000
)
-
1
,
1
);
...
...
@@ -874,18 +1084,38 @@ static int at91_ts_register(struct at91_adc_state *st,
__set_bit
(
EV_ABS
,
input
->
evbit
);
__set_bit
(
EV_KEY
,
input
->
evbit
);
__set_bit
(
BTN_TOUCH
,
input
->
keybit
);
input_set_abs_params
(
input
,
ABS_X
,
0
,
(
1
<<
MAX_POS_BITS
)
-
1
,
0
,
0
);
input_set_abs_params
(
input
,
ABS_Y
,
0
,
(
1
<<
MAX_POS_BITS
)
-
1
,
0
,
0
);
if
(
st
->
caps
->
has_tsmr
)
{
input_set_abs_params
(
input
,
ABS_X
,
0
,
(
1
<<
MAX_POS_BITS
)
-
1
,
0
,
0
);
input_set_abs_params
(
input
,
ABS_Y
,
0
,
(
1
<<
MAX_POS_BITS
)
-
1
,
0
,
0
);
input_set_abs_params
(
input
,
ABS_PRESSURE
,
0
,
0xffffff
,
0
,
0
);
}
else
{
if
(
st
->
touchscreen_type
!=
ATMEL_ADC_TOUCHSCREEN_4WIRE
)
{
dev_err
(
&
pdev
->
dev
,
"This touchscreen controller only support 4 wires
\n
"
);
ret
=
-
EINVAL
;
goto
err
;
}
input_set_abs_params
(
input
,
ABS_X
,
0
,
(
1
<<
MAX_RLPOS_BITS
)
-
1
,
0
,
0
);
input_set_abs_params
(
input
,
ABS_Y
,
0
,
(
1
<<
MAX_RLPOS_BITS
)
-
1
,
0
,
0
);
}
st
->
ts_input
=
input
;
input_set_drvdata
(
input
,
st
);
ret
=
input_register_device
(
input
);
if
(
ret
)
input_free_device
(
st
->
ts_input
)
;
goto
err
;
return
ret
;
err:
input_free_device
(
st
->
ts_input
);
return
ret
;
}
static
void
at91_ts_unregister
(
struct
at91_adc_state
*
st
)
...
...
@@ -943,11 +1173,13 @@ static int at91_adc_probe(struct platform_device *pdev)
*/
at91_adc_writel
(
st
,
AT91_ADC_CR
,
AT91_ADC_SWRST
);
at91_adc_writel
(
st
,
AT91_ADC_IDR
,
0xFFFFFFFF
);
ret
=
request_irq
(
st
->
irq
,
at91_adc_interrupt
,
0
,
pdev
->
dev
.
driver
->
name
,
idev
);
if
(
st
->
caps
->
has_tsmr
)
ret
=
request_irq
(
st
->
irq
,
at91_adc_9x5_interrupt
,
0
,
pdev
->
dev
.
driver
->
name
,
idev
);
else
ret
=
request_irq
(
st
->
irq
,
at91_adc_rl_interrupt
,
0
,
pdev
->
dev
.
driver
->
name
,
idev
);
if
(
ret
)
{
dev_err
(
&
pdev
->
dev
,
"Failed to allocate IRQ.
\n
"
);
return
ret
;
...
...
@@ -1051,12 +1283,6 @@ static int at91_adc_probe(struct platform_device *pdev)
goto
error_disable_adc_clk
;
}
}
else
{
if
(
!
st
->
caps
->
has_tsmr
)
{
dev_err
(
&
pdev
->
dev
,
"We don't support non-TSMR adc
\n
"
);
ret
=
-
ENODEV
;
goto
error_disable_adc_clk
;
}
ret
=
at91_ts_register
(
st
,
pdev
);
if
(
ret
)
goto
error_disable_adc_clk
;
...
...
@@ -1120,6 +1346,20 @@ static struct at91_adc_caps at91sam9260_caps = {
},
};
static
struct
at91_adc_caps
at91sam9rl_caps
=
{
.
has_ts
=
true
,
.
calc_startup_ticks
=
calc_startup_ticks_9260
,
/* same as 9260 */
.
num_channels
=
6
,
.
registers
=
{
.
channel_base
=
AT91_ADC_CHR
(
0
),
.
drdy_mask
=
AT91_ADC_DRDY
,
.
status_register
=
AT91_ADC_SR
,
.
trigger_register
=
AT91_ADC_TRGR_9G45
,
.
mr_prescal_mask
=
AT91_ADC_PRESCAL_9260
,
.
mr_startup_mask
=
AT91_ADC_STARTUP_9G45
,
},
};
static
struct
at91_adc_caps
at91sam9g45_caps
=
{
.
has_ts
=
true
,
.
calc_startup_ticks
=
calc_startup_ticks_9260
,
/* same as 9260 */
...
...
@@ -1154,6 +1394,7 @@ static struct at91_adc_caps at91sam9x5_caps = {
static
const
struct
of_device_id
at91_adc_dt_ids
[]
=
{
{
.
compatible
=
"atmel,at91sam9260-adc"
,
.
data
=
&
at91sam9260_caps
},
{
.
compatible
=
"atmel,at91sam9rl-adc"
,
.
data
=
&
at91sam9rl_caps
},
{
.
compatible
=
"atmel,at91sam9g45-adc"
,
.
data
=
&
at91sam9g45_caps
},
{
.
compatible
=
"atmel,at91sam9x5-adc"
,
.
data
=
&
at91sam9x5_caps
},
{},
...
...
@@ -1164,6 +1405,9 @@ static const struct platform_device_id at91_adc_ids[] = {
{
.
name
=
"at91sam9260-adc"
,
.
driver_data
=
(
unsigned
long
)
&
at91sam9260_caps
,
},
{
.
name
=
"at91sam9rl-adc"
,
.
driver_data
=
(
unsigned
long
)
&
at91sam9rl_caps
,
},
{
.
name
=
"at91sam9g45-adc"
,
.
driver_data
=
(
unsigned
long
)
&
at91sam9g45_caps
,
...
...
drivers/input/touchscreen/Kconfig
浏览文件 @
6a84872a
...
...
@@ -550,18 +550,6 @@ config TOUCHSCREEN_TI_AM335X_TSC
To compile this driver as a module, choose M here: the
module will be called ti_am335x_tsc.
config TOUCHSCREEN_ATMEL_TSADCC
tristate "Atmel Touchscreen Interface"
depends on ARCH_AT91
help
Say Y here if you have a 4-wire touchscreen connected to the
ADC Controller on your Atmel SoC.
If unsure, say N.
To compile this driver as a module, choose M here: the
module will be called atmel_tsadcc.
config TOUCHSCREEN_UCB1400
tristate "Philips UCB1400 touchscreen"
depends on AC97_BUS
...
...
drivers/input/touchscreen/Makefile
浏览文件 @
6a84872a
...
...
@@ -13,7 +13,6 @@ obj-$(CONFIG_TOUCHSCREEN_AD7879_I2C) += ad7879-i2c.o
obj-$(CONFIG_TOUCHSCREEN_AD7879_SPI)
+=
ad7879-spi.o
obj-$(CONFIG_TOUCHSCREEN_ADS7846)
+=
ads7846.o
obj-$(CONFIG_TOUCHSCREEN_ATMEL_MXT)
+=
atmel_mxt_ts.o
obj-$(CONFIG_TOUCHSCREEN_ATMEL_TSADCC)
+=
atmel_tsadcc.o
obj-$(CONFIG_TOUCHSCREEN_AUO_PIXCIR)
+=
auo-pixcir-ts.o
obj-$(CONFIG_TOUCHSCREEN_BU21013)
+=
bu21013_ts.o
obj-$(CONFIG_TOUCHSCREEN_CY8CTMG110)
+=
cy8ctmg110_ts.o
...
...
drivers/input/touchscreen/atmel_tsadcc.c
已删除
100644 → 0
浏览文件 @
d82b4013
/*
* Atmel Touch Screen Driver
*
* Copyright (c) 2008 ATMEL
* Copyright (c) 2008 Dan Liang
* Copyright (c) 2008 TimeSys Corporation
* Copyright (c) 2008 Justin Waters
*
* Based on touchscreen code from Atmel Corporation.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#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/platform_data/atmel.h>
#include <mach/cpu.h>
/* Register definitions based on AT91SAM9RL64 preliminary draft datasheet */
#define ATMEL_TSADCC_CR 0x00
/* Control register */
#define ATMEL_TSADCC_SWRST (1 << 0)
/* Software Reset*/
#define ATMEL_TSADCC_START (1 << 1)
/* Start conversion */
#define ATMEL_TSADCC_MR 0x04
/* Mode register */
#define ATMEL_TSADCC_TSAMOD (3 << 0)
/* ADC mode */
#define ATMEL_TSADCC_TSAMOD_ADC_ONLY_MODE (0x0)
/* ADC Mode */
#define ATMEL_TSADCC_TSAMOD_TS_ONLY_MODE (0x1)
/* Touch Screen Only Mode */
#define ATMEL_TSADCC_LOWRES (1 << 4)
/* Resolution selection */
#define ATMEL_TSADCC_SLEEP (1 << 5)
/* Sleep mode */
#define ATMEL_TSADCC_PENDET (1 << 6)
/* Pen Detect selection */
#define ATMEL_TSADCC_PRES (1 << 7)
/* Pressure Measurement Selection */
#define ATMEL_TSADCC_PRESCAL (0x3f << 8)
/* Prescalar Rate Selection */
#define ATMEL_TSADCC_EPRESCAL (0xff << 8)
/* Prescalar Rate Selection (Extended) */
#define ATMEL_TSADCC_STARTUP (0x7f << 16)
/* Start Up time */
#define ATMEL_TSADCC_SHTIM (0xf << 24)
/* Sample & Hold time */
#define ATMEL_TSADCC_PENDBC (0xf << 28)
/* Pen Detect debouncing time */
#define ATMEL_TSADCC_TRGR 0x08
/* Trigger register */
#define ATMEL_TSADCC_TRGMOD (7 << 0)
/* Trigger mode */
#define ATMEL_TSADCC_TRGMOD_NONE (0 << 0)
#define ATMEL_TSADCC_TRGMOD_EXT_RISING (1 << 0)
#define ATMEL_TSADCC_TRGMOD_EXT_FALLING (2 << 0)
#define ATMEL_TSADCC_TRGMOD_EXT_ANY (3 << 0)
#define ATMEL_TSADCC_TRGMOD_PENDET (4 << 0)
#define ATMEL_TSADCC_TRGMOD_PERIOD (5 << 0)
#define ATMEL_TSADCC_TRGMOD_CONTINUOUS (6 << 0)
#define ATMEL_TSADCC_TRGPER (0xffff << 16)
/* Trigger period */
#define ATMEL_TSADCC_TSR 0x0C
/* Touch Screen register */
#define ATMEL_TSADCC_TSFREQ (0xf << 0)
/* TS Frequency in Interleaved mode */
#define ATMEL_TSADCC_TSSHTIM (0xf << 24)
/* Sample & Hold time */
#define ATMEL_TSADCC_CHER 0x10
/* Channel Enable register */
#define ATMEL_TSADCC_CHDR 0x14
/* Channel Disable register */
#define ATMEL_TSADCC_CHSR 0x18
/* Channel Status register */
#define ATMEL_TSADCC_CH(n) (1 << (n))
/* Channel number */
#define ATMEL_TSADCC_SR 0x1C
/* Status register */
#define ATMEL_TSADCC_EOC(n) (1 << ((n)+0))
/* End of conversion for channel N */
#define ATMEL_TSADCC_OVRE(n) (1 << ((n)+8))
/* Overrun error for channel N */
#define ATMEL_TSADCC_DRDY (1 << 16)
/* Data Ready */
#define ATMEL_TSADCC_GOVRE (1 << 17)
/* General Overrun Error */
#define ATMEL_TSADCC_ENDRX (1 << 18)
/* End of RX Buffer */
#define ATMEL_TSADCC_RXBUFF (1 << 19)
/* TX Buffer full */
#define ATMEL_TSADCC_PENCNT (1 << 20)
/* Pen contact */
#define ATMEL_TSADCC_NOCNT (1 << 21)
/* No contact */
#define ATMEL_TSADCC_LCDR 0x20
/* Last Converted Data register */
#define ATMEL_TSADCC_DATA (0x3ff << 0)
/* Channel data */
#define ATMEL_TSADCC_IER 0x24
/* Interrupt Enable register */
#define ATMEL_TSADCC_IDR 0x28
/* Interrupt Disable register */
#define ATMEL_TSADCC_IMR 0x2C
/* Interrupt Mask register */
#define ATMEL_TSADCC_CDR0 0x30
/* Channel Data 0 */
#define ATMEL_TSADCC_CDR1 0x34
/* Channel Data 1 */
#define ATMEL_TSADCC_CDR2 0x38
/* Channel Data 2 */
#define ATMEL_TSADCC_CDR3 0x3C
/* Channel Data 3 */
#define ATMEL_TSADCC_CDR4 0x40
/* Channel Data 4 */
#define ATMEL_TSADCC_CDR5 0x44
/* Channel Data 5 */
#define ATMEL_TSADCC_XPOS 0x50
#define ATMEL_TSADCC_Z1DAT 0x54
#define ATMEL_TSADCC_Z2DAT 0x58
#define PRESCALER_VAL(x) ((x) >> 8)
#define ADC_DEFAULT_CLOCK 100000
struct
atmel_tsadcc
{
struct
input_dev
*
input
;
char
phys
[
32
];
struct
clk
*
clk
;
int
irq
;
unsigned
int
prev_absx
;
unsigned
int
prev_absy
;
unsigned
char
bufferedmeasure
;
};
static
void
__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))
static
irqreturn_t
atmel_tsadcc_interrupt
(
int
irq
,
void
*
dev
)
{
struct
atmel_tsadcc
*
ts_dev
=
(
struct
atmel_tsadcc
*
)
dev
;
struct
input_dev
*
input_dev
=
ts_dev
->
input
;
unsigned
int
status
;
unsigned
int
reg
;
status
=
atmel_tsadcc_read
(
ATMEL_TSADCC_SR
);
status
&=
atmel_tsadcc_read
(
ATMEL_TSADCC_IMR
);
if
(
status
&
ATMEL_TSADCC_NOCNT
)
{
/* Contact lost */
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
);
ts_dev
->
bufferedmeasure
=
0
;
input_sync
(
input_dev
);
}
else
if
(
status
&
ATMEL_TSADCC_PENCNT
)
{
/* Pen detected */
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
));
}
else
if
(
status
&
ATMEL_TSADCC_EOC
(
3
))
{
/* Conversion finished */
if
(
ts_dev
->
bufferedmeasure
)
{
/* Last measurement is always discarded, since it can
* be erroneous.
* Always report previous measurement */
input_report_abs
(
input_dev
,
ABS_X
,
ts_dev
->
prev_absx
);
input_report_abs
(
input_dev
,
ABS_Y
,
ts_dev
->
prev_absy
);
input_report_key
(
input_dev
,
BTN_TOUCH
,
1
);
input_sync
(
input_dev
);
}
else
ts_dev
->
bufferedmeasure
=
1
;
/* Now make new measurement */
ts_dev
->
prev_absx
=
atmel_tsadcc_read
(
ATMEL_TSADCC_CDR3
)
<<
10
;
ts_dev
->
prev_absx
/=
atmel_tsadcc_read
(
ATMEL_TSADCC_CDR2
);
ts_dev
->
prev_absy
=
atmel_tsadcc_read
(
ATMEL_TSADCC_CDR1
)
<<
10
;
ts_dev
->
prev_absy
/=
atmel_tsadcc_read
(
ATMEL_TSADCC_CDR0
);
}
return
IRQ_HANDLED
;
}
/*
* The functions for inserting/removing us as a module.
*/
static
int
atmel_tsadcc_probe
(
struct
platform_device
*
pdev
)
{
struct
atmel_tsadcc
*
ts_dev
;
struct
input_dev
*
input_dev
;
struct
resource
*
res
;
struct
at91_tsadcc_data
*
pdata
=
dev_get_platdata
(
&
pdev
->
dev
);
int
err
;
unsigned
int
prsc
;
unsigned
int
reg
;
if
(
!
pdata
)
return
-
EINVAL
;
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
(
struct
atmel_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
;
goto
err_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
;
goto
err_free_dev
;
}
if
(
!
request_mem_region
(
res
->
start
,
resource_size
(
res
),
"atmel tsadcc regs"
))
{
dev_err
(
&
pdev
->
dev
,
"resources is unavailable.
\n
"
);
err
=
-
EBUSY
;
goto
err_free_dev
;
}
tsc_base
=
ioremap
(
res
->
start
,
resource_size
(
res
));
if
(
!
tsc_base
)
{
dev_err
(
&
pdev
->
dev
,
"failed to map registers.
\n
"
);
err
=
-
ENOMEM
;
goto
err_release_mem
;
}
err
=
request_irq
(
ts_dev
->
irq
,
atmel_tsadcc_interrupt
,
0
,
pdev
->
dev
.
driver
->
name
,
ts_dev
);
if
(
err
)
{
dev_err
(
&
pdev
->
dev
,
"failed to allocate irq.
\n
"
);
goto
err_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
);
goto
err_free_irq
;
}
ts_dev
->
input
=
input_dev
;
ts_dev
->
bufferedmeasure
=
0
;
snprintf
(
ts_dev
->
phys
,
sizeof
(
ts_dev
->
phys
),
"%s/input0"
,
dev_name
(
&
pdev
->
dev
));
input_dev
->
name
=
"atmel touch screen controller"
;
input_dev
->
phys
=
ts_dev
->
phys
;
input_dev
->
dev
.
parent
=
&
pdev
->
dev
;
__set_bit
(
EV_ABS
,
input_dev
->
evbit
);
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_capability
(
input_dev
,
EV_KEY
,
BTN_TOUCH
);
/* 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
);
if
(
!
pdata
->
adc_clock
)
pdata
->
adc_clock
=
ADC_DEFAULT_CLOCK
;
prsc
=
(
prsc
/
(
2
*
pdata
->
adc_clock
))
-
1
;
/* saturate if this value is too high */
if
(
cpu_is_at91sam9rl
())
{
if
(
prsc
>
PRESCALER_VAL
(
ATMEL_TSADCC_PRESCAL
))
prsc
=
PRESCALER_VAL
(
ATMEL_TSADCC_PRESCAL
);
}
else
{
if
(
prsc
>
PRESCALER_VAL
(
ATMEL_TSADCC_EPRESCAL
))
prsc
=
PRESCALER_VAL
(
ATMEL_TSADCC_EPRESCAL
);
}
dev_info
(
&
pdev
->
dev
,
"Prescaler is set at: %d
\n
"
,
prsc
);
reg
=
ATMEL_TSADCC_TSAMOD_TS_ONLY_MODE
|
((
0x00
<<
5
)
&
ATMEL_TSADCC_SLEEP
)
|
/* Normal Mode */
((
0x01
<<
6
)
&
ATMEL_TSADCC_PENDET
)
|
/* Enable Pen Detect */
(
prsc
<<
8
)
|
((
0x26
<<
16
)
&
ATMEL_TSADCC_STARTUP
)
|
((
pdata
->
pendet_debounce
<<
28
)
&
ATMEL_TSADCC_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
,
(
pdata
->
ts_sample_hold_time
<<
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
)
goto
err_fail
;
return
0
;
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
,
resource_size
(
res
));
err_free_dev:
input_free_device
(
input_dev
);
err_free_mem:
kfree
(
ts_dev
);
return
err
;
}
static
int
atmel_tsadcc_remove
(
struct
platform_device
*
pdev
)
{
struct
atmel_tsadcc
*
ts_dev
=
platform_get_drvdata
(
pdev
);
struct
resource
*
res
;
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
,
resource_size
(
res
));
clk_disable
(
ts_dev
->
clk
);
clk_put
(
ts_dev
->
clk
);
kfree
(
ts_dev
);
return
0
;
}
static
struct
platform_driver
atmel_tsadcc_driver
=
{
.
probe
=
atmel_tsadcc_probe
,
.
remove
=
atmel_tsadcc_remove
,
.
driver
=
{
.
name
=
"atmel_tsadcc"
,
},
};
module_platform_driver
(
atmel_tsadcc_driver
);
MODULE_LICENSE
(
"GPL"
);
MODULE_DESCRIPTION
(
"Atmel TouchScreen Driver"
);
MODULE_AUTHOR
(
"Dan Liang <dan.liang@atmel.com>"
);
include/linux/clk/at91_pmc.h
浏览文件 @
6a84872a
...
...
@@ -155,6 +155,7 @@ extern void __iomem *at91_pmc_base;
#define AT91_PMC_LOCKB (1 << 2)
/* PLLB Lock */
#define AT91_PMC_MCKRDY (1 << 3)
/* Master Clock */
#define AT91_PMC_LOCKU (1 << 6)
/* UPLL Lock [some SAM9] */
#define AT91_PMC_OSCSEL (1 << 7)
/* Slow Oscillator Selection [some SAM9] */
#define AT91_PMC_PCK0RDY (1 << 8)
/* Programmable Clock 0 */
#define AT91_PMC_PCK1RDY (1 << 9)
/* Programmable Clock 1 */
#define AT91_PMC_PCK2RDY (1 << 10)
/* Programmable Clock 2 */
...
...
include/linux/platform_data/at91_adc.h
浏览文件 @
6a84872a
...
...
@@ -7,23 +7,10 @@
#ifndef _AT91_ADC_H_
#define _AT91_ADC_H_
/**
* struct at91_adc_reg_desc - Various informations relative to registers
* @channel_base: Base offset for the channel data registers
* @drdy_mask: Mask of the DRDY field in the relevant registers
(Interruptions registers mostly)
* @status_register: Offset of the Interrupt Status Register
* @trigger_register: Offset of the Trigger setup register
* @mr_prescal_mask: Mask of the PRESCAL field in the adc MR register
* @mr_startup_mask: Mask of the STARTUP field in the adc MR register
*/
struct
at91_adc_reg_desc
{
u8
channel_base
;
u32
drdy_mask
;
u8
status_register
;
u8
trigger_register
;
u32
mr_prescal_mask
;
u32
mr_startup_mask
;
enum
atmel_adc_ts_type
{
ATMEL_ADC_TOUCHSCREEN_NONE
=
0
,
ATMEL_ADC_TOUCHSCREEN_4WIRE
=
4
,
ATMEL_ADC_TOUCHSCREEN_5WIRE
=
5
,
};
/**
...
...
@@ -42,23 +29,21 @@ struct at91_adc_trigger {
/**
* struct at91_adc_data - platform data for ADC driver
* @channels_used: channels in use on the board as a bitmask
* @num_channels: global number of channels available on the board
* @registers: Registers definition on the board
* @startup_time: startup time of the ADC in microseconds
* @trigger_list: Triggers available in the ADC
* @trigger_number: Number of triggers available in the ADC
* @use_external_triggers: does the board has external triggers availables
* @vref: Reference voltage for the ADC in millivolts
* @touchscreen_type: If a touchscreen is connected, its type (4 or 5 wires)
*/
struct
at91_adc_data
{
unsigned
long
channels_used
;
u8
num_channels
;
struct
at91_adc_reg_desc
*
registers
;
u8
startup_time
;
struct
at91_adc_trigger
*
trigger_list
;
u8
trigger_number
;
bool
use_external_triggers
;
u16
vref
;
enum
atmel_adc_ts_type
touchscreen_type
;
};
extern
void
__init
at91_add_device_adc
(
struct
at91_adc_data
*
data
);
...
...
include/linux/platform_data/atmel.h
浏览文件 @
6a84872a
...
...
@@ -87,13 +87,6 @@ struct atmel_uart_data {
int
rts_gpio
;
/* optional RTS GPIO */
};
/* Touchscreen Controller */
struct
at91_tsadcc_data
{
unsigned
int
adc_clock
;
u8
pendet_debounce
;
u8
ts_sample_hold_time
;
};
/* CAN */
struct
at91_can_data
{
void
(
*
transceiver_switch
)(
int
on
);
...
...
sound/soc/atmel/sam9g20_wm8731.c
浏览文件 @
6a84872a
...
...
@@ -48,7 +48,6 @@
#include <asm/mach-types.h>
#include <mach/hardware.h>
#include <mach/gpio.h>
#include "../codecs/wm8731.h"
#include "atmel-pcm.h"
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录