diff options
-rw-r--r-- | bootloader/imx233.c | 6 | ||||
-rw-r--r-- | firmware/SOURCES | 2 | ||||
-rw-r--r-- | firmware/drivers/synaptics-rmi.c | 77 | ||||
-rw-r--r-- | firmware/export/synaptics-rmi.h | 63 | ||||
-rw-r--r-- | firmware/target/arm/imx233/sansa-fuzeplus/button-fuzeplus.c | 134 | ||||
-rw-r--r-- | firmware/target/arm/imx233/sansa-fuzeplus/button-target.h | 1 |
6 files changed, 283 insertions, 0 deletions
diff --git a/bootloader/imx233.c b/bootloader/imx233.c index cded5a119a..868d6e499f 100644 --- a/bootloader/imx233.c +++ b/bootloader/imx233.c | |||
@@ -35,6 +35,8 @@ | |||
35 | #include "disk.h" | 35 | #include "disk.h" |
36 | #include "panic.h" | 36 | #include "panic.h" |
37 | #include "power.h" | 37 | #include "power.h" |
38 | #include "pinctrl-imx233.h" | ||
39 | #include "system-target.h" | ||
38 | 40 | ||
39 | int show_logo(void); | 41 | int show_logo(void); |
40 | 42 | ||
@@ -58,6 +60,10 @@ void main(void) | |||
58 | 60 | ||
59 | button_init_device(); | 61 | button_init_device(); |
60 | 62 | ||
63 | button_debug_screen(); | ||
64 | |||
65 | power_off(); | ||
66 | |||
61 | ret = storage_init(); | 67 | ret = storage_init(); |
62 | if(ret < 0) | 68 | if(ret < 0) |
63 | error(EATA, ret, true); | 69 | error(EATA, ret, true); |
diff --git a/firmware/SOURCES b/firmware/SOURCES index e5eb0e6e1f..6d4ef9fe2b 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES | |||
@@ -1435,6 +1435,8 @@ target/arm/as3525/lcd-as-e200v2-fuze-fuzev2.S | |||
1435 | 1435 | ||
1436 | #ifdef SANSA_FUZEPLUS | 1436 | #ifdef SANSA_FUZEPLUS |
1437 | #ifndef SIMULATOR | 1437 | #ifndef SIMULATOR |
1438 | drivers/generic_i2c.c | ||
1439 | drivers/synaptics-rmi.c | ||
1438 | target/arm/imx233/sansa-fuzeplus/backlight-fuzeplus.c | 1440 | target/arm/imx233/sansa-fuzeplus/backlight-fuzeplus.c |
1439 | target/arm/imx233/sansa-fuzeplus/lcd-fuzeplus.c | 1441 | target/arm/imx233/sansa-fuzeplus/lcd-fuzeplus.c |
1440 | target/arm/imx233/sansa-fuzeplus/button-fuzeplus.c | 1442 | target/arm/imx233/sansa-fuzeplus/button-fuzeplus.c |
diff --git a/firmware/drivers/synaptics-rmi.c b/firmware/drivers/synaptics-rmi.c new file mode 100644 index 0000000000..c6a1bae168 --- /dev/null +++ b/firmware/drivers/synaptics-rmi.c | |||
@@ -0,0 +1,77 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2011 by Amaury Pouly | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | #include "system.h" | ||
22 | #include "generic_i2c.h" | ||
23 | #include "synaptics-rmi.h" | ||
24 | |||
25 | static int rmi_cur_page; | ||
26 | static int rmi_i2c_addr; | ||
27 | static int rmi_i2c_bus; | ||
28 | |||
29 | /* NOTE: | ||
30 | * RMI over i2c supports some special aliases on page 0x2 but this driver don't | ||
31 | * use them */ | ||
32 | |||
33 | int rmi_init(int i2c_bus_index, int i2c_dev_addr) | ||
34 | { | ||
35 | rmi_i2c_bus = i2c_bus_index; | ||
36 | rmi_i2c_addr = i2c_dev_addr; | ||
37 | rmi_cur_page = 0x4; | ||
38 | return 0; | ||
39 | } | ||
40 | |||
41 | static int rmi_select_page(unsigned char page) | ||
42 | { | ||
43 | /* Lazy page select */ | ||
44 | if(page != rmi_cur_page) | ||
45 | { | ||
46 | rmi_cur_page = page; | ||
47 | return i2c_write_data(rmi_i2c_bus, rmi_i2c_addr, RMI_PAGE_SELECT, &page, 1); | ||
48 | } | ||
49 | else | ||
50 | return 0; | ||
51 | } | ||
52 | |||
53 | int rmi_read(int address, int byte_count, unsigned char *buffer) | ||
54 | { | ||
55 | if(rmi_select_page(address >> 8) < 0) | ||
56 | return -1; | ||
57 | return i2c_read_data(rmi_i2c_bus, rmi_i2c_addr, address & 0xff, buffer, byte_count); | ||
58 | } | ||
59 | |||
60 | int rmi_read_single(int address) | ||
61 | { | ||
62 | unsigned char c; | ||
63 | int ret = rmi_read(address, 1, &c); | ||
64 | return ret < 0 ? ret : c; | ||
65 | } | ||
66 | |||
67 | int rmi_write(int address, int byte_count, const unsigned char *buffer) | ||
68 | { | ||
69 | if(rmi_select_page(address >> 8) < 0) | ||
70 | return -1; | ||
71 | return i2c_write_data(rmi_i2c_bus, rmi_i2c_addr, address & 0xff, buffer, byte_count); | ||
72 | } | ||
73 | |||
74 | int rmi_write_single(int address, unsigned char byte) | ||
75 | { | ||
76 | return rmi_write(address, 1, &byte); | ||
77 | } | ||
diff --git a/firmware/export/synaptics-rmi.h b/firmware/export/synaptics-rmi.h new file mode 100644 index 0000000000..59fbb807ab --- /dev/null +++ b/firmware/export/synaptics-rmi.h | |||
@@ -0,0 +1,63 @@ | |||
1 | /*************************************************************************** | ||
2 | * __________ __ ___. | ||
3 | * Open \______ \ ____ ____ | | _\_ |__ _______ ___ | ||
4 | * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ / | ||
5 | * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < < | ||
6 | * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \ | ||
7 | * \/ \/ \/ \/ \/ | ||
8 | * $Id$ | ||
9 | * | ||
10 | * Copyright (C) 2011 by Amaury Pouly | ||
11 | * | ||
12 | * This program is free software; you can redistribute it and/or | ||
13 | * modify it under the terms of the GNU General Public License | ||
14 | * as published by the Free Software Foundation; either version 2 | ||
15 | * of the License, or (at your option) any later version. | ||
16 | * | ||
17 | * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY | ||
18 | * KIND, either express or implied. | ||
19 | * | ||
20 | ****************************************************************************/ | ||
21 | #ifndef SYNAPTICS_RMI_H | ||
22 | #define SYNAPTICS_RMI_H | ||
23 | |||
24 | #define RMI_PAGE_SELECT 0xff /* $xxff */ | ||
25 | #define RMI_MAKE_REG(fn, reg) (((fn) << 8) | (reg)) | ||
26 | #define RMI_DEVICE_CONTROL 0x0 /* $0000 */ | ||
27 | #define RMI_INTERRUPT_ENABLE 0x1 /* $0001 */ | ||
28 | #define RMI_INTERRUPT_REQUEST 0x3 /* $0003 */ | ||
29 | #define RMI_PRODUCT_ID 0x210 /* $0210 */ | ||
30 | #define RMI_PRODUCT_ID_LEN 16 | ||
31 | #define RMI_2D_TOUCHPAD_FUNCTION 0x10 | ||
32 | #define RMI_FUNCTION_PRESENCE(fn) RMI_MAKE_REG(0x03, fn) /* $03xx */ | ||
33 | #define RMI_FUNCTION_VERSION(fn) RMI_MAKE_REG(fn, 0) /* $xx00 */ | ||
34 | #define RMI_DATA_REGISTER(data_src) RMI_MAKE_REG(0x4, data_src) /* $04xx */ | ||
35 | /* 2D TouchPad/ClearPad */ | ||
36 | #define RMI_2D_REG(reg) RMI_MAKE_REG(RMI_2D_TOUCHPAD_FUNCTION, reg) | ||
37 | #define RMI_2D_SENSOR_PROP1(sens) RMI_2D_REG(8 * (sens) + 0x2) | ||
38 | #define RMI_2D_SENSOR_PROP2(sens) RMI_2D_REG(8 * (sens) + 0x3) | ||
39 | #define RMI_2D_SENSOR_XMAX_MSB(s) RMI_2D_REG(8 * (s) + 0x4) | ||
40 | #define RMI_2D_SENSOR_XMAX_LSB(s) RMI_2D_REG(8 * (s) + 0x5) | ||
41 | #define RMI_2D_SENSOR_YMAX_MSB(s) RMI_2D_REG(8 * (s) + 0x6) | ||
42 | #define RMI_2D_SENSOR_YMAX_LSB(s) RMI_2D_REG(8 * (s) + 0x7) | ||
43 | #define RMI_2D_SENSOR_RESOLUTION(s) RMI_2D_REG(8 * (s) + 0x8) | ||
44 | |||
45 | /* Initialize the RMI driver, the i2c_bus_index is the bus index returned by | ||
46 | * the generic_i2c driver; the i2c_dev_addr is the i2c address of the device. | ||
47 | * NOTE: the driver automatically handles the page select mechanism used for | ||
48 | * RMI over i2c and assumes a standard page select register at 0xff. */ | ||
49 | int rmi_init(int i2c_bus_index, int i2c_dev_addr); | ||
50 | /* Read one or more registers. | ||
51 | * WARNING: don't cross a page boundary ! */ | ||
52 | int rmi_read(int address, int byte_count, unsigned char *buffer); | ||
53 | /* Read a single register (return -1 on error) | ||
54 | * WARNING: beware of register consistency (N x read 1 byte != reads N bytes) */ | ||
55 | int rmi_read_single(int address); /* return byte value or <0 in case of error */ | ||
56 | /* Write one of more register | ||
57 | * WARNING: don't cross a page boundary ! */ | ||
58 | int rmi_write(int address, int byte_count, const unsigned char *buffer); | ||
59 | /* Write one register | ||
60 | * WARNING: don't cross a page boundary ! */ | ||
61 | int rmi_write_single(int address, unsigned char byte); | ||
62 | |||
63 | #endif | ||
diff --git a/firmware/target/arm/imx233/sansa-fuzeplus/button-fuzeplus.c b/firmware/target/arm/imx233/sansa-fuzeplus/button-fuzeplus.c index 4882f243aa..1b8116b1b7 100644 --- a/firmware/target/arm/imx233/sansa-fuzeplus/button-fuzeplus.c +++ b/firmware/target/arm/imx233/sansa-fuzeplus/button-fuzeplus.c | |||
@@ -22,9 +22,143 @@ | |||
22 | #include "system.h" | 22 | #include "system.h" |
23 | #include "system-target.h" | 23 | #include "system-target.h" |
24 | #include "pinctrl-imx233.h" | 24 | #include "pinctrl-imx233.h" |
25 | #include "generic_i2c.h" | ||
26 | #include "synaptics-rmi.h" | ||
27 | #include "lcd.h" | ||
28 | |||
29 | static void i2c_scl_dir(bool out) | ||
30 | { | ||
31 | imx233_enable_gpio_output(0, 30, out); | ||
32 | } | ||
33 | |||
34 | static void i2c_sda_dir(bool out) | ||
35 | { | ||
36 | imx233_enable_gpio_output(0, 31, out); | ||
37 | } | ||
38 | |||
39 | static void i2c_scl_out(bool high) | ||
40 | { | ||
41 | imx233_set_gpio_output(0, 30, high); | ||
42 | } | ||
43 | |||
44 | static void i2c_sda_out(bool high) | ||
45 | { | ||
46 | imx233_set_gpio_output(0, 31, high); | ||
47 | } | ||
48 | |||
49 | static bool i2c_scl_in(void) | ||
50 | { | ||
51 | return imx233_get_gpio_input_mask(0, 1 << 30); | ||
52 | } | ||
53 | |||
54 | static bool i2c_sda_in(void) | ||
55 | { | ||
56 | return imx233_get_gpio_input_mask(0, 1 << 31); | ||
57 | } | ||
58 | |||
59 | static void i2c_delay(int d) | ||
60 | { | ||
61 | udelay(d); | ||
62 | } | ||
63 | |||
64 | struct i2c_interface btn_i2c = | ||
65 | { | ||
66 | .scl_dir = i2c_scl_dir, | ||
67 | .sda_dir = i2c_sda_dir, | ||
68 | .scl_out = i2c_scl_out, | ||
69 | .sda_out = i2c_sda_out, | ||
70 | .scl_in = i2c_scl_in, | ||
71 | .sda_in = i2c_sda_in, | ||
72 | .delay = i2c_delay, | ||
73 | .delay_hd_sta = 4, | ||
74 | .delay_hd_dat = 5, | ||
75 | .delay_su_dat = 1, | ||
76 | .delay_su_sto = 4, | ||
77 | .delay_su_sta = 5, | ||
78 | .delay_thigh = 4 | ||
79 | }; | ||
80 | |||
81 | int rmi_i2c_bus = -1; | ||
82 | |||
83 | void button_debug_screen(void) | ||
84 | { | ||
85 | char product_id[RMI_PRODUCT_ID_LEN]; | ||
86 | rmi_read(RMI_PRODUCT_ID, RMI_PRODUCT_ID_LEN, product_id); | ||
87 | |||
88 | while(1) | ||
89 | { | ||
90 | lcd_clear_display(); | ||
91 | int btns = button_read_device(); | ||
92 | lcd_putsf(0, 0, "button bitmap: %x", btns); | ||
93 | lcd_putsf(0, 1, "RMI: product=%s", product_id); | ||
94 | lcd_putsf(0, 2, "touchpad presence: %x", rmi_read_single(RMI_FUNCTION_PRESENCE(RMI_2D_TOUCHPAD_FUNCTION))); | ||
95 | lcd_putsf(0, 3, "sensor prop: %x", rmi_read_single(RMI_2D_SENSOR_PROP2(0))); | ||
96 | int x_max = rmi_read_single(RMI_2D_SENSOR_XMAX_MSB(0)) << 8 | rmi_read_single(RMI_2D_SENSOR_XMAX_LSB(0)); | ||
97 | int y_max = rmi_read_single(RMI_2D_SENSOR_YMAX_MSB(0)) << 8 | rmi_read_single(RMI_2D_SENSOR_YMAX_LSB(0)); | ||
98 | lcd_putsf(0, 4, "xmax=%d ymax=%d res=%d", x_max, y_max, | ||
99 | rmi_read_single(RMI_2D_SENSOR_RESOLUTION(0))); | ||
100 | lcd_putsf(0, 5, "din0=%x", imx233_get_gpio_input_mask(0, 0x08000000)); | ||
101 | lcd_putsf(0, 6, "dev ctl: %x", rmi_read_single(RMI_DEVICE_CONTROL)); | ||
102 | lcd_putsf(0, 7, "int en: %x", rmi_read_single(RMI_INTERRUPT_ENABLE)); | ||
103 | lcd_putsf(0, 8, "int req: %x", rmi_read_single(RMI_INTERRUPT_REQUEST)); | ||
104 | union | ||
105 | { | ||
106 | unsigned char data[10]; | ||
107 | struct | ||
108 | { | ||
109 | unsigned char absolute_misc; | ||
110 | unsigned char absolute_z; | ||
111 | unsigned char absolute_x_msb; | ||
112 | unsigned char absolute_x_lsb; | ||
113 | unsigned char absolute_y_msb; | ||
114 | unsigned char absolute_y_lsb; | ||
115 | signed char relative_x; /* signed */ | ||
116 | signed char relative_y; /* signed */ | ||
117 | unsigned char gesture_misc; | ||
118 | unsigned char gesture_flick; | ||
119 | } __attribute__((packed)) s; | ||
120 | }u; | ||
121 | int absolute_x = u.s.absolute_x_msb << 8 | u.s.absolute_x_lsb; | ||
122 | int absolute_y = u.s.absolute_y_msb << 8 | u.s.absolute_y_lsb; | ||
123 | rmi_read(RMI_DATA_REGISTER(0), 10, u.data); | ||
124 | lcd_putsf(0, 9, "abs: %d %d", absolute_x, absolute_y); | ||
125 | lcd_putsf(0, 10, "rel: %d %d", (int)u.s.relative_x, (int)u.s.relative_y); | ||
126 | lcd_putsf(0, 11, "gesture: %x %x", u.s.gesture_misc, u.s.gesture_flick); | ||
127 | |||
128 | lcd_update(); | ||
129 | |||
130 | if(btns & BUTTON_POWER) | ||
131 | break; | ||
132 | yield(); | ||
133 | } | ||
134 | } | ||
25 | 135 | ||
26 | void button_init_device(void) | 136 | void button_init_device(void) |
27 | { | 137 | { |
138 | rmi_i2c_bus = i2c_add_node(&btn_i2c); | ||
139 | rmi_init(rmi_i2c_bus, 0x40); | ||
140 | |||
141 | /* Synaptics TouchPad information: | ||
142 | * - product id: 1533 | ||
143 | * - nr function: 1 (0x10 = 2D touchpad) | ||
144 | * 2D Touchpad information (function 0x10) | ||
145 | * - nr data sources: 3 | ||
146 | * - standard layout | ||
147 | * - extra data registers: 7 | ||
148 | * - nr sensors: 1 | ||
149 | * 2D Touchpad Sensor #0 information: | ||
150 | * - has relative data: yes | ||
151 | * - has palm detect: yes | ||
152 | * - has multi finger: yes | ||
153 | * - has enhanced gesture: yes | ||
154 | * - has scroller: no | ||
155 | * - has 2D scrollers: no | ||
156 | * - Maximum X: 3009 | ||
157 | * - Maxumum Y: 1974 | ||
158 | * - Resolution: 82 | ||
159 | * | ||
160 | * ATTENTION line: B0P27 asserted low | ||
161 | */ | ||
28 | } | 162 | } |
29 | 163 | ||
30 | int button_read_device(void) | 164 | int button_read_device(void) |
diff --git a/firmware/target/arm/imx233/sansa-fuzeplus/button-target.h b/firmware/target/arm/imx233/sansa-fuzeplus/button-target.h index 81bbc34511..f22c06882f 100644 --- a/firmware/target/arm/imx233/sansa-fuzeplus/button-target.h +++ b/firmware/target/arm/imx233/sansa-fuzeplus/button-target.h | |||
@@ -26,6 +26,7 @@ | |||
26 | 26 | ||
27 | void button_init_device(void); | 27 | void button_init_device(void); |
28 | int button_read_device(void); | 28 | int button_read_device(void); |
29 | void button_debug_screen(void); | ||
29 | 30 | ||
30 | /* Main unit's buttons */ | 31 | /* Main unit's buttons */ |
31 | #define BUTTON_POWER 0x00000001 | 32 | #define BUTTON_POWER 0x00000001 |