summaryrefslogtreecommitdiffstats
path: root/firmware
diff options
context:
space:
mode:
authorBertrik Sikken <bertrik@sikken.nl>2009-08-01 14:58:52 +0000
committerBertrik Sikken <bertrik@sikken.nl>2009-08-01 14:58:52 +0000
commitbcd510db66838e8df0df05980b237f0e6b2adad7 (patch)
treefd1771c2d8e2988cb474289ae1a7403ff0b06346 /firmware
parent9bcc6701bf1689d3d06089b1d239f1ecfb9e9844 (diff)
downloadrockbox-bcd510db66838e8df0df05980b237f0e6b2adad7.tar.gz
rockbox-bcd510db66838e8df0df05980b237f0e6b2adad7.tar.bz2
rockbox-bcd510db66838e8df0df05980b237f0e6b2adad7.zip
Samsung YP-S3: implement button driver for the touch keys (and the hold/power switch)
git-svn-id: svn://svn.rockbox.org/rockbox/trunk@22093 a1c6a512-1295-4272-9138-f99709370657
Diffstat (limited to 'firmware')
-rw-r--r--firmware/SOURCES3
-rw-r--r--firmware/target/arm/s5l8700/yps3/button-yps3.c146
2 files changed, 147 insertions, 2 deletions
diff --git a/firmware/SOURCES b/firmware/SOURCES
index b60bb29a4a..844e10a489 100644
--- a/firmware/SOURCES
+++ b/firmware/SOURCES
@@ -1412,12 +1412,11 @@ target/arm/samsung/yh925/powermgmt-yh925.c
#ifdef SAMSUNG_YPS3
/* TODO: currently including all files for the bootloader DFU test program */
-drivers/generic_i2c.c
-drivers/mcs3080.c
target/arm/s5l8700/adc-s5l8700.c
target/arm/s5l8700/i2c-s5l8700.c
target/arm/s5l8700/kernel-s5l8700.c
target/arm/s5l8700/timer-s5l8700.c
+target/arm/s5l8700/yps3/button-yps3.c
target/arm/s5l8700/yps3/lcd-yps3.c
target/arm/s5l8700/yps3/fmradio-i2c-yps3.c
target/arm/s5l8700/yps3/backlight-yps3.c
diff --git a/firmware/target/arm/s5l8700/yps3/button-yps3.c b/firmware/target/arm/s5l8700/yps3/button-yps3.c
new file mode 100644
index 0000000000..74b5e130c3
--- /dev/null
+++ b/firmware/target/arm/s5l8700/yps3/button-yps3.c
@@ -0,0 +1,146 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id$
+ *
+ * Copyright (C) 2009 Bertrik Sikken
+ *
+ * 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.
+ *
+ * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
+ * KIND, either express or implied.
+ *
+ ****************************************************************************/
+
+#include <stdbool.h>
+#include "config.h"
+
+#include "inttypes.h"
+#include "s5l8700.h"
+#include "button-target.h"
+
+/* Button driver for the touch keys on the Samsung YP-S3
+
+ The exact controller is not known, but it is likely from Melfas.
+
+ The protocol is as follows:
+ * the communication is done using three signals: DRDY, DCLK and DOUT
+ * in the idle state these signals are all high.
+ * when a key is touched or released, the key controller pulls down DRDY
+ and outputs the first bit of a 20-bit word on its DOUT signal.
+ * the CPU stores the bit, then acknowledges it by toggling the DCLK signal.
+ * the key controller prepares the next bit, then toggles its DRDY output,
+ unless all 20 bits have been transferred (in that case it stays high).
+ * the 20-bit word contains separate bits for each button, some fixed bits
+ and a bit indicating the number of keys pressed (modulo 2).
+ */
+
+
+void button_init_device(void)
+{
+ /* P0.5/P1.0 power switch input */
+ PCON0 &= ~(3 << 10);
+ PCON1 &= ~0x0000000F;
+
+ /* P1.5 DATA, P1.6 DRDY inputs (touch key controller) */
+ PCON1 &= ~0x0FF00000;
+
+ /* P3.4 DCLK output (touch key controller) */
+ PCON3 = (PCON3 & ~0x000F0000) | 0x00010000;
+ PDAT3 |= (1 << 4);
+
+ /* P4.3 hold switch input */
+ PCON4 &= ~0x0000F000;
+}
+
+static unsigned int tkey_read(void)
+{
+ static int value = 0;
+ int i;
+
+ /* check activity */
+ if (PDAT1 & (1 << 6)) {
+ return value;
+ }
+
+ /* get key bits */
+ value = 0;
+ for (i = 0; i < 10; i++) {
+ /* sample bit from falling edge of DRDY */
+ while ((PDAT1 & (1 << 6)) != 0);
+ value <<= 1;
+ if (PDAT1 & (1 << 5)) {
+ value |= 1;
+ }
+
+ /* acknowledge on DCLK */
+ PDAT3 &= ~(1 << 4);
+
+ /* sample bit from rising edge of DRDY */
+ while ((PDAT1 & (1 << 6)) == 0);
+ value <<= 1;
+ if (PDAT1 & (1 << 5)) {
+ value |= 1;
+ }
+
+ /* acknowledge on DCLK */
+ PDAT3 |= (1 << 4);
+ }
+ return value;
+}
+
+
+int button_read_device(void)
+{
+ int buttons = 0;
+ static unsigned int data;
+
+ /* hold switch */
+ if (button_hold()) {
+ return 0;
+ }
+
+ /* power button */
+ if (PDAT1 & (1 << 0)) {
+ buttons |= BUTTON_POWER;
+ }
+
+ /* touch keys */
+ data = tkey_read();
+ if (data & (1 << 9)) {
+ buttons |= BUTTON_BACK;
+ }
+ if (data & (1 << 8)) {
+ buttons |= BUTTON_UP;
+ }
+ if (data & (1 << 7)) {
+ buttons |= BUTTON_MENU;
+ }
+ if (data & (1 << 6)) {
+ buttons |= BUTTON_LEFT;
+ }
+ if (data & (1 << 5)) {
+ buttons |= BUTTON_SELECT;
+ }
+ if (data & (1 << 4)) {
+ buttons |= BUTTON_RIGHT;
+ }
+ if (data & (1 << 3)) {
+ buttons |= BUTTON_DOWN;
+ }
+
+ return buttons;
+}
+
+bool button_hold(void)
+{
+ return (PDAT4 & (1 << 3));
+}
+