summaryrefslogtreecommitdiff
path: root/firmware/target
diff options
context:
space:
mode:
authorLorenzo Miori <memoryS60@gmail.com>2013-09-10 22:48:34 +0200
committerThomas Martitz <kugel@rockbox.org>2014-02-05 09:56:21 +0100
commite876f4df6d240bd2e319b1e63be95a625f049a97 (patch)
treece2fe1b24650e3be7a6cd2d346d29090a5422a8c /firmware/target
parentb828b9d99bff2acc0e1f543f3176fd4b632cba68 (diff)
Samsung YP-R1 target port
This is the basic port to the new target Samsung YP-R1, which runs on a similar platform as YP-R0. Port is usable, although there are still some optimizations that have to be done. Change-Id: If83a8e386369e413581753780c159026d9e41f04
Diffstat (limited to 'firmware/target')
-rw-r--r--firmware/target/hosted/samsungypr/gpio_ypr.c16
-rw-r--r--firmware/target/hosted/samsungypr/ypr0/gpio-target.h1
-rw-r--r--firmware/target/hosted/samsungypr/ypr1/audio-ypr1.c76
-rw-r--r--firmware/target/hosted/samsungypr/ypr1/backlight-ypr1.c66
-rw-r--r--firmware/target/hosted/samsungypr/ypr1/button-target.h63
-rw-r--r--firmware/target/hosted/samsungypr/ypr1/button-ypr1.c130
-rw-r--r--firmware/target/hosted/samsungypr/ypr1/gpio-target.h67
-rw-r--r--firmware/target/hosted/samsungypr/ypr1/ioctl-ypr1.h230
-rw-r--r--firmware/target/hosted/samsungypr/ypr1/mcs5000-ypr1.c94
-rw-r--r--firmware/target/hosted/samsungypr/ypr1/mcs5000.h189
-rw-r--r--firmware/target/hosted/samsungypr/ypr1/pmu-ypr1.c51
-rw-r--r--firmware/target/hosted/samsungypr/ypr1/pmu-ypr1.h88
-rw-r--r--firmware/target/hosted/samsungypr/ypr1/powermgmt-ypr1.c153
-rw-r--r--firmware/target/hosted/samsungypr/ypr1/system-ypr1.c67
-rw-r--r--firmware/target/hosted/samsungypr/ypr1/wmcodec-ypr1.c90
-rw-r--r--firmware/target/hosted/samsungypr/ypr1/ypr1.make24
16 files changed, 1397 insertions, 8 deletions
diff --git a/firmware/target/hosted/samsungypr/gpio_ypr.c b/firmware/target/hosted/samsungypr/gpio_ypr.c
index 40855fba41..1782d4cfe4 100644
--- a/firmware/target/hosted/samsungypr/gpio_ypr.c
+++ b/firmware/target/hosted/samsungypr/gpio_ypr.c
@@ -6,7 +6,7 @@
* Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
* \/ \/ \/ \/ \/
*
- * Module wrapper for GPIO, using /dev/r0GPIO (r0Gpio.ko) of Samsung YP-R0
+ * Module wrapper for GPIO, using kernel module of Samsung YP-R0/YP-R1
*
* Copyright (c) 2011 Lorenzo Miori
*
@@ -26,23 +26,23 @@
#include <gpio-target.h> /* includes common ioctl device definitions */
#include <sys/ioctl.h>
-static int r0_gpio_dev = 0;
+static int gpio_dev = 0;
void gpio_init(void)
{
- r0_gpio_dev = open("/dev/r0GPIO", O_RDONLY);
- if (r0_gpio_dev < 0)
- printf("/dev/r0GPIO open error!");
+ gpio_dev = open(GPIO_DEVICE, O_RDONLY);
+ if (gpio_dev < 0)
+ printf("GPIO device open error!");
}
void gpio_close(void)
{
- if (r0_gpio_dev >= 0)
- close(r0_gpio_dev);
+ if (gpio_dev >= 0)
+ close(gpio_dev);
}
int gpio_control(int request, int num, int mode, int val)
{
struct gpio_info r = { .num = num, .mode = mode, .val = val, };
- return ioctl(r0_gpio_dev, request, &r);
+ return ioctl(gpio_dev, request, &r);
}
diff --git a/firmware/target/hosted/samsungypr/ypr0/gpio-target.h b/firmware/target/hosted/samsungypr/ypr0/gpio-target.h
index c27e07bf40..f27b176195 100644
--- a/firmware/target/hosted/samsungypr/ypr0/gpio-target.h
+++ b/firmware/target/hosted/samsungypr/ypr0/gpio-target.h
@@ -53,6 +53,7 @@
#define GPIO_LEFT_KEY GPIO2_28
#define GPIO_RIGHT_KEY GPIO3_7
+#define GPIO_DEVICE "/dev/r0GPIO"
void gpio_init(void);
void gpio_close(void);
diff --git a/firmware/target/hosted/samsungypr/ypr1/audio-ypr1.c b/firmware/target/hosted/samsungypr/ypr1/audio-ypr1.c
new file mode 100644
index 0000000000..05b77a8ff2
--- /dev/null
+++ b/firmware/target/hosted/samsungypr/ypr1/audio-ypr1.c
@@ -0,0 +1,76 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ *
+ * Copyright (C) 2008 by Nils Wallménius
+ *
+ * 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 "config.h"
+#include "system.h"
+#include "audiohw.h"
+#include "audio.h"
+
+void audiohw_enable_tone_controls(bool enable);
+void audiohw_enable_depth_3d(bool enable);
+
+/* Set the audio source for IIS TX */
+void audio_set_output_source(int source)
+{
+ switch (source)
+ {
+ default:
+ case AUDIO_SRC_PLAYBACK:
+ /*
+ audiohw_enable_tone_controls(true);
+ audiohw_enable_depth_3d(true);
+ */
+ break;
+
+ case AUDIO_SRC_FMRADIO:
+ /* Analog path doesn't support these and digital radio playback
+ * cannot be done without mixing on the MCU if voice is to be
+ * heard. Any recording should match what is heard. */
+ audiohw_enable_tone_controls(false);
+ audiohw_enable_depth_3d(false);
+ break;
+ }
+}
+
+void audio_input_mux(int source, unsigned int flags)
+{
+ /* Prevent pops from unneeded switching */
+ static int last_source = AUDIO_SRC_PLAYBACK;
+ bool recording = flags & SRCF_RECORDING;
+ static bool last_recording = false;
+
+ switch (source)
+ {
+ default:
+ source = AUDIO_SRC_PLAYBACK;
+ /* Fallthrough */
+ case AUDIO_SRC_PLAYBACK: /* playback - no recording */
+ if (source != last_source)
+ audiohw_set_recsrc(AUDIO_SRC_PLAYBACK, false);
+ break;
+
+ case AUDIO_SRC_FMRADIO: /* recording and playback */
+ if (source != last_source || recording != last_recording)
+ audiohw_set_recsrc(AUDIO_SRC_FMRADIO, recording);
+ break;
+ }
+
+ last_source = source;
+ last_recording = recording;
+}
diff --git a/firmware/target/hosted/samsungypr/ypr1/backlight-ypr1.c b/firmware/target/hosted/samsungypr/ypr1/backlight-ypr1.c
new file mode 100644
index 0000000000..e4f0457cf9
--- /dev/null
+++ b/firmware/target/hosted/samsungypr/ypr1/backlight-ypr1.c
@@ -0,0 +1,66 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ *
+ * Copyright (C) 2013 by Lorenzo Miori
+ *
+ * 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 "config.h"
+#include "system.h"
+#include "backlight.h"
+#include "backlight-target.h"
+#include "lcd.h"
+#include "lcd-target.h"
+#include "pmu-ypr1.h"
+
+static bool backlight_on_status = true; /* Is on or off? */
+
+bool _backlight_init(void)
+{
+ /* We have nothing to do */
+ return true;
+}
+
+void _backlight_on(void)
+{
+ if (!backlight_on_status) {
+ _backlight_set_brightness(backlight_brightness);
+ }
+
+ backlight_on_status = true;
+
+}
+
+void _backlight_off(void)
+{
+ if (backlight_on_status) {
+ _backlight_set_brightness(0);
+ }
+
+ backlight_on_status = false;
+}
+
+void _backlight_set_brightness(int brightness)
+{
+ /* Just another check... */
+ if (brightness > MAX_BRIGHTNESS_SETTING) {
+ brightness = MAX_BRIGHTNESS_SETTING;
+ }
+ if (brightness < 0) {
+ brightness = MIN_BRIGHTNESS_SETTING;
+ }
+ /* Do the appropriate ioctl on the linux module */
+ pmu_ioctl(MAX8819_IOCTL_LCD_DIM_CTRL, &brightness);
+}
diff --git a/firmware/target/hosted/samsungypr/ypr1/button-target.h b/firmware/target/hosted/samsungypr/ypr1/button-target.h
new file mode 100644
index 0000000000..fc618258c0
--- /dev/null
+++ b/firmware/target/hosted/samsungypr/ypr1/button-target.h
@@ -0,0 +1,63 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ *
+ * Copyright (C) 2013 by Lorenzo Miori
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+#ifndef _BUTTON_TARGET_H_
+#define _BUTTON_TARGET_H_
+
+void button_close_device(void);
+
+/* Logical buttons key codes */
+#define BUTTON_VOL_UP 0x00000001
+#define BUTTON_VOL_DOWN 0x00000002
+#define BUTTON_POWER 0x00000004
+#define BUTTON_RIGHT 0x00000008
+#define BUTTON_LEFT 0x00000012
+
+/* Touch Screen Area Buttons */
+#define BUTTON_TOPLEFT 0x00000010
+#define BUTTON_TOPMIDDLE 0x00000020
+#define BUTTON_TOPRIGHT 0x00000040
+#define BUTTON_MIDLEFT 0x00000080
+#define BUTTON_CENTER 0x00000100
+#define BUTTON_MIDRIGHT 0x00000200
+#define BUTTON_BOTTOMLEFT 0x00000400
+#define BUTTON_BOTTOMMIDDLE 0x00000800
+#define BUTTON_BOTTOMRIGHT 0x00001000
+
+/* All the buttons */
+#define BUTTON_MAIN (BUTTON_VOL_UP | BUTTON_VOL_DOWN | BUTTON_POWER | \
+ BUTTON_RIGHT|BUTTON_LEFT| BUTTON_TOPLEFT | BUTTON_TOPMIDDLE | \
+ BUTTON_TOPRIGHT | BUTTON_MIDLEFT | BUTTON_CENTER | \
+ BUTTON_MIDRIGHT | BUTTON_BOTTOMLEFT | BUTTON_BOTTOMMIDDLE | \
+ BUTTON_BOTTOMRIGHT) /* all buttons */
+
+/* Default touchscreen calibration
+ * TODO this is not 100% accurate. X-AXIS must be slightly moved to the right
+ */
+#define DEFAULT_TOUCHSCREEN_CALIBRATION {.A=0x0000AD7C, .B=0xFFFFFC70, \
+ .C=0xFF6632E0, .D=0xFFFFFF1A, .E=0xFFFF5D08, \
+ .F=0xFFFC4230, .divider=0xFFFF54E0}
+
+/* Software power-off */
+#define POWEROFF_BUTTON BUTTON_POWER
+/* About 3 seconds */
+#define POWEROFF_COUNT 10
+
+#endif /* _BUTTON_TARGET_H_ */
diff --git a/firmware/target/hosted/samsungypr/ypr1/button-ypr1.c b/firmware/target/hosted/samsungypr/ypr1/button-ypr1.c
new file mode 100644
index 0000000000..09891cfaf6
--- /dev/null
+++ b/firmware/target/hosted/samsungypr/ypr1/button-ypr1.c
@@ -0,0 +1,130 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ * $Id: button-sdl.c 30482 2011-09-08 14:53:28Z kugel $
+ *
+ * Copyright (C) 2013 Lorenzo Miori
+ *
+ * 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 "config.h"
+#include "button.h"
+#include "kernel.h"
+#include "system.h"
+#include "button-target.h"
+
+#include <gpio-target.h> /* For headphones sense and buttons */
+#include "mcs5000.h" /* Touchscreen controller */
+#include "ioctl-ypr1.h"
+
+enum {
+ STATE_UNKNOWN,
+ STATE_UP,
+ STATE_DOWN,
+};
+
+static int last_x = 0;
+static int last_y = 0;
+static int last_touch_state = STATE_UNKNOWN;
+
+int button_read_device(int *data)
+{
+ int key = BUTTON_NONE;
+ int read_size;
+ struct mcs5000_raw_data touchpad_data;
+
+ /* Check for all the keys */
+ if (!gpio_control(DEV_CTRL_GPIO_IS_HIGH, GPIO_VOL_UP_KEY, 0, 0)) {
+ key |= BUTTON_VOL_UP;
+ }
+ if (!gpio_control(DEV_CTRL_GPIO_IS_HIGH, GPIO_VOL_DOWN_KEY, 0, 0)) {
+ key |= BUTTON_VOL_DOWN;
+ }
+ if (gpio_control(DEV_CTRL_GPIO_IS_HIGH, GPIO_POWER_KEY, 0, 0)) {
+ key |= BUTTON_POWER;
+ }
+
+ read_size = mcs5000_read(&touchpad_data);
+
+ if (read_size == sizeof(struct mcs5000_raw_data)) {
+ /* Generate UP and DOWN events */
+ if (touchpad_data.inputInfo & INPUT_TYPE_SINGLE) {
+ last_touch_state = STATE_DOWN;
+ }
+ else {
+ last_touch_state = STATE_UP;
+ }
+ /* Swap coordinates here */
+#if CONFIG_ORIENTATION == SCREEN_PORTRAIT
+ last_x = (touchpad_data.yHigh << 8) | touchpad_data.yLow;
+ last_y = (touchpad_data.xHigh << 8) | touchpad_data.xLow;
+#else
+ last_x = (touchpad_data.xHigh << 8) | touchpad_data.xLow;
+ last_y = (touchpad_data.yHigh << 8) | touchpad_data.yLow;
+#endif
+ }
+
+ int tkey = touchscreen_to_pixels(last_x, last_y, data);
+
+ if (last_touch_state == STATE_DOWN) {
+ key |= tkey;
+ }
+
+ return key;
+}
+
+#ifndef HAS_BUTTON_HOLD
+void touchscreen_enable_device(bool en)
+{
+ if (en) {
+ mcs5000_power();
+ }
+ else {
+ mcs5000_shutdown();
+ }
+}
+#endif
+
+bool headphones_inserted(void)
+{
+ /* GPIO low - 0 - means headphones inserted */
+ return !gpio_control(DEV_CTRL_GPIO_IS_HIGH, GPIO_HEADPHONE_SENSE, 0, 0);
+}
+
+void button_init_device(void)
+{
+ /* Setup GPIO pin for headphone sense, copied from OF
+ * Pins for the other buttons are already set up by OF button module
+ */
+ gpio_control(DEV_CTRL_GPIO_SET_MUX, GPIO_HEADPHONE_SENSE, 4, 0);
+ gpio_control(DEV_CTRL_GPIO_SET_INPUT, GPIO_HEADPHONE_SENSE, 4, 0);
+
+ /* Turn on touchscreen */
+ mcs5000_init();
+ mcs5000_power();
+ mcs5000_set_hand(RIGHT_HAND);
+}
+
+#ifdef BUTTON_DRIVER_CLOSE
+/* I'm not sure it's called at shutdown...give a check! */
+void button_close_device(void)
+{
+ gpio_control(DEV_CTRL_GPIO_UNSET_MUX, GPIO_HEADPHONE_SENSE, 0, 0);
+
+ /* Turn off touchscreen device */
+ mcs5000_shutdown();
+ mcs5000_close();
+}
+#endif /* BUTTON_DRIVER_CLOSE */
diff --git a/firmware/target/hosted/samsungypr/ypr1/gpio-target.h b/firmware/target/hosted/samsungypr/ypr1/gpio-target.h
new file mode 100644
index 0000000000..f439e786de
--- /dev/null
+++ b/firmware/target/hosted/samsungypr/ypr1/gpio-target.h
@@ -0,0 +1,67 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ *
+ * Module wrapper for GPIO, using /dev/r1GPIO (r1Gpio.ko) of Samsung YP-R1
+ *
+ * Copyright (c) 2013 Lorenzo Miori
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+#ifndef GPIO_TARGET_H
+#define GPIO_TARGET_H
+
+#include "ioctl-ypr1.h"
+
+/* Some meaningful pins used in the YP-R1 */
+
+#define GPIO_HEADPHONE_SENSE GPIO1_31
+/* I2C bus for the SI4079 FM, WM1808 codec and RTC radio chip */
+#define GPIO_I2C_CLK1 GPIO1_0
+#define GPIO_I2C_DAT1 GPIO1_1
+/* I2C bus for the fuel gauge MAX17040 */
+#define GPIO_I2C_CLK2 GPIO2_12
+#define GPIO_I2C_DAT2 GPIO2_13
+/* SI4079 pins - powerup and interrupt */
+#define GPIO_FM_SEARCH GPIO1_4
+#define GPIO_FM_BUS_EN GPIO1_10
+#define GPIO_MUTE GPIO2_17
+#define EXT_POWER_DET GPIO1_26
+/* Low disabled, high enabled */
+#define TV_OUT_ENABLE GPIO1_17
+/* Battery charging */
+#define CHARGE_ENABLE GPIO1_18
+#define CHARGE_STATUS GPIO_D13
+/* This should be high when connecting a special port to the board... */
+#define PBA_CHECK_ENABLED GPIO2_1
+/* TODO see if this is the source of massive battery drain
+ * touchscreen and usb 3.3v power control line
+ */
+#define POWER_3V3_LINE_CONTROL GPIO1_16
+
+/* Keypad */
+
+#define GPIO_VOL_UP_KEY GPIO1_20
+#define GPIO_VOL_DOWN_KEY GPIO1_21
+#define GPIO_POWER_KEY GPIO2_16
+
+#define GPIO_DEVICE "/dev/r1Gpio"
+
+void gpio_init(void);
+void gpio_close(void);
+int gpio_control_struct(int request, struct gpio_info pin);
+int gpio_control(int request, int num, int mode, int val);
+
+#endif /* GPIO_TARGET_H */
diff --git a/firmware/target/hosted/samsungypr/ypr1/ioctl-ypr1.h b/firmware/target/hosted/samsungypr/ypr1/ioctl-ypr1.h
new file mode 100644
index 0000000000..4ac7a1c4b5
--- /dev/null
+++ b/firmware/target/hosted/samsungypr/ypr1/ioctl-ypr1.h
@@ -0,0 +1,230 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ *
+ * Copyright (C) 2013 Lorenzo Miori
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+#ifndef __DEV_IOCTL_YPR0_H__
+#define __DEV_IOCTL_YPR0_H__
+
+#include <sys/ioctl.h>
+#include "stdint.h"
+
+/**
+ * This is the wrapper to r1Bat.ko module with the possible
+ * ioctl calls, retrieved by RE
+ * The "Fuel gauge" - battery controller - is the MAX17040GT
+ */
+
+/* A typical read spans 2 registers */
+typedef struct {
+ uint8_t addr;
+ uint8_t reg1;
+ uint8_t reg2;
+}__attribute__((packed)) max17040_request;
+
+/* Registers are 16-bit wide */
+#define MAX17040_GET_BATTERY_VOLTAGE 0x80045800
+#define MAX17040_GET_BATTERY_CAPACITY 0x80045801
+#define MAX17040_READ_REG 0x80035803
+#define MAX17040_WRITE_REG 0x40035802
+
+void max17040_init(void);
+void max17040_close(void);
+int max17040_ioctl(int request, int *data);
+
+/**
+ * This is the wrapper to r1Gpio.ko module with the possible
+ * ioctl calls
+ * TODO move this into a more generic file for ypr platform
+ */
+
+struct gpio_info {
+ int num;
+ int mode;
+ int val;
+} __attribute__((packed));
+
+/* Strangely for whatever reason magic differs from R0 (A vs. G) */
+#define IOCTL_GPIO_MAGIC 'A'
+
+#define E_IOCTL_GPIO_SET_MUX 0
+#define E_IOCTL_GPIO_UNSET_MUX 1
+#define E_IOCTL_GPIO_SET_TYPE 2
+#define E_IOCTL_GPIO_SET_OUTPUT 3
+#define E_IOCTL_GPIO_SET_INPUT 4
+#define E_IOCTL_GPIO_SET_HIGH 5
+#define E_IOCTL_GPIO_SET_LOW 6
+#define E_IOCTL_GPIO_GET_VAL 7
+#define E_IOCTL_GPIO_IS_HIGH 8
+#define E_IOCTL_GPIO_MAX_NR 9
+
+#define DEV_CTRL_GPIO_SET_MUX _IOW(IOCTL_GPIO_MAGIC, 0, struct gpio_info)
+#define DEV_CTRL_GPIO_UNSET_MUX _IOW(IOCTL_GPIO_MAGIC, 1, struct gpio_info)
+#define DEV_CTRL_GPIO_SET_TYPE _IOW(IOCTL_GPIO_MAGIC, 2, struct gpio_info)
+#define DEV_CTRL_GPIO_SET_OUTPUT _IOW(IOCTL_GPIO_MAGIC, 3, struct gpio_info)
+#define DEV_CTRL_GPIO_SET_INPUT _IOW(IOCTL_GPIO_MAGIC, 4, struct gpio_info)
+#define DEV_CTRL_GPIO_SET_HIGH _IOW(IOCTL_GPIO_MAGIC, 5, struct gpio_info)
+#define DEV_CTRL_GPIO_SET_LOW _IOW(IOCTL_GPIO_MAGIC, 6, struct gpio_info)
+#define DEV_CTRL_GPIO_GET_VAL _IOW(IOCTL_GPIO_MAGIC, 7, struct gpio_info)
+#define DEV_CTRL_GPIO_IS_HIGH _IOW(IOCTL_GPIO_MAGIC, 8, struct gpio_info)
+
+
+typedef enum
+{
+ GPIO1_0 = 0, /* GPIO group 1 start */
+ GPIO1_1,
+ GPIO1_2,
+ GPIO1_3,
+ GPIO1_4,
+ GPIO1_5,
+ GPIO1_6,
+ GPIO1_7,
+ GPIO1_8,
+ GPIO1_9,
+ GPIO1_10,
+ GPIO1_11,
+ GPIO1_12,
+ GPIO1_13,
+ GPIO1_14,
+ GPIO1_15,
+ GPIO1_16,
+ GPIO1_17,
+ GPIO1_18,
+ GPIO1_19,
+ GPIO1_20,
+ GPIO1_21,
+ GPIO1_22,
+ GPIO1_23,
+ GPIO1_24,
+ GPIO1_25,
+ GPIO1_26,
+ GPIO1_27,
+ GPIO1_28,
+ GPIO1_29,
+ GPIO1_30,
+ GPIO1_31,
+ GPIO2_0, /* GPIO group 2 start */
+ GPIO2_1,
+ GPIO2_2,
+ GPIO2_3,
+ GPIO2_4,
+ GPIO2_5,
+ GPIO2_6,
+ GPIO2_7,
+ GPIO2_8,
+ GPIO2_9,
+ GPIO2_10,
+ GPIO2_11,
+ GPIO2_12,
+ GPIO2_13,
+ GPIO2_14,
+ GPIO2_15,
+ GPIO2_16,
+ GPIO2_17,
+ GPIO2_18,
+ GPIO2_19,
+ GPIO2_20,
+ GPIO2_21,
+ GPIO2_22,
+ GPIO2_23,
+ GPIO2_24,
+ GPIO2_25,
+ GPIO2_26,
+ GPIO2_27,
+ GPIO2_28,
+ GPIO2_29,
+ GPIO2_30,
+ GPIO2_31,
+ GPIO3_0, /* GPIO group 3 start */
+ GPIO3_1,
+ GPIO3_2,
+ GPIO3_3,
+ GPIO3_4,
+ GPIO3_5,
+ GPIO3_6,
+ GPIO3_7,
+ GPIO3_8,
+ GPIO3_9,
+ GPIO3_10,
+ GPIO3_11,
+ GPIO3_12,
+ GPIO3_13,
+ GPIO3_14,
+ GPIO3_15,
+ GPIO3_16,
+ GPIO3_17,
+ GPIO3_18,
+ GPIO3_19,
+ GPIO3_20,
+ GPIO3_21,
+ GPIO3_22,
+ GPIO3_23,
+ GPIO3_24,
+ GPIO3_25,
+ GPIO3_26,
+ GPIO3_27,
+ GPIO3_28,
+ GPIO3_29,
+ GPIO3_30,
+ GPIO3_31,
+}R0_MX37_GPIO;
+
+typedef enum
+{
+ CONFIG_ALT0,
+ CONFIG_ALT1,
+ CONFIG_ALT2,
+ CONFIG_ALT3,
+ CONFIG_ALT4,
+ CONFIG_ALT5,
+ CONFIG_ALT6,
+ CONFIG_ALT7,
+ CONFIG_GPIO,
+ CONFIG_SION = 0x01 << 4,
+ CONFIG_DEFAULT
+} R0_MX37_PIN_CONFIG;
+
+#ifndef __MACH_MX37_IOMUX_H__
+typedef enum
+{
+ PAD_CTL_SRE_SLOW = 0x0 << 0,
+ PAD_CTL_SRE_FAST = 0x1 << 0,
+ PAD_CTL_DRV_LOW = 0x0 << 1,
+ PAD_CTL_DRV_MEDIUM = 0x1 << 1,
+ PAD_CTL_DRV_HIGH = 0x2 << 1,
+ PAD_CTL_DRV_MAX = 0x3 << 1,
+ PAD_CTL_ODE_OPENDRAIN_NONE = 0x0 << 3,
+ PAD_CTL_ODE_OPENDRAIN_ENABLE = 0x1 << 3,
+ PAD_CTL_100K_PD = 0x0 << 4,
+ PAD_CTL_47K_PU = 0x1 << 4,
+ PAD_CTL_100K_PU = 0x2 << 4,
+ PAD_CTL_22K_PU = 0x3 << 4,
+ PAD_CTL_PUE_KEEPER = 0x0 << 6,
+ PAD_CTL_PUE_PULL = 0x1 << 6,
+ PAD_CTL_PKE_NONE = 0x0 << 7,
+ PAD_CTL_PKE_ENABLE = 0x1 << 7,
+ PAD_CTL_HYS_NONE = 0x0 << 8,
+ PAD_CTL_HYS_ENABLE = 0x1 << 8,
+ PAD_CTL_DDR_INPUT_CMOS = 0x0 << 9,
+ PAD_CTL_DDR_INPUT_DDR = 0x1 << 9,
+ PAD_CTL_DRV_VOT_LOW = 0x0 << 13,
+ PAD_CTL_DRV_VOT_HIGH = 0x1 << 13,
+} R0_MX37_PAD_CONFIG;
+#endif
+
+#endif /* __DEV_IOCTL_YPR0_H__ */
diff --git a/firmware/target/hosted/samsungypr/ypr1/mcs5000-ypr1.c b/firmware/target/hosted/samsungypr/ypr1/mcs5000-ypr1.c
new file mode 100644
index 0000000000..bfd9922768
--- /dev/null
+++ b/firmware/target/hosted/samsungypr/ypr1/mcs5000-ypr1.c
@@ -0,0 +1,94 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ *
+ * Copyright (c) 2013 Lorenzo Miori
+ *
+ * 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 <unistd.h>
+#include <fcntl.h>
+#include "sys/ioctl.h"
+
+#include "mcs5000.h"
+#include "ioctl-ypr1.h"
+
+/* TODO Settings like hand and sensitivity will be lost when shutting device off!! */
+
+static int mcs5000_dev = -1;
+static int mcs5000_hand_setting = RIGHT_HAND;
+
+void mcs5000_init(void)
+{
+ mcs5000_dev = open("/dev/r1Touch", O_RDONLY);
+}
+
+void mcs5000_close(void)
+{
+ if (mcs5000_dev > 0)
+ close(mcs5000_dev);
+}
+
+void mcs5000_power(void)
+{
+ ioctl(mcs5000_dev, DEV_CTRL_TOUCH_ON);
+ ioctl(mcs5000_dev, DEV_CTRL_TOUCH_IDLE);
+ mcs5000_set_hand(mcs5000_hand_setting);
+}
+
+void mcs5000_shutdown(void)
+{
+ /* save setting before shutting down the device */
+ ioctl(mcs5000_dev, DEV_CTRL_TOUCH_FLUSH);
+ ioctl(mcs5000_dev, DEV_CTRL_TOUCH_RESET);
+ ioctl(mcs5000_dev, DEV_CTRL_TOUCH_OFF);
+}
+
+void mcs5000_set_hand(int hand)
+{
+ switch (hand)
+ {
+ case RIGHT_HAND:
+ ioctl(mcs5000_dev, DEV_CTRL_TOUCH_RIGHTHAND);
+ break;
+ case LEFT_HAND:
+ ioctl(mcs5000_dev, DEV_CTRL_TOUCH_LEFTHAND);
+ break;
+ default:
+ break;
+ }
+ mcs5000_hand_setting = hand;
+}
+
+void mcs5000_set_sensitivity(int level)
+{
+ ioctl(mcs5000_dev, DEV_CTRL_TOUCH_SET_SENSE, &level);
+}
+
+int mcs5000_read(struct mcs5000_raw_data *touchData)
+{
+ /* work around GCC bug: aligned attribute is not applied to automatic
+ * variables, and apparently this structure has a large alignment requirement
+ * (if it's only automatic with implicit 8-byte alignment then the
+ * touchscreen misbehaves). The bug seems fixed in gcc 4.6.x
+ * See http://http://gcc.gnu.org/bugzilla/show_bug.cgi?id=16660
+ * Also: packet and aligned attributes don't really work together so
+ * the aligned attribute cannot be attached to the struct declaration */
+ static struct mcs5000_raw_data touchpad_data __attribute__((aligned(256)));
+ ssize_t ret;
+ ret = read(mcs5000_dev, &touchpad_data, sizeof(struct mcs5000_raw_data));
+ *touchData = touchpad_data;
+ return ret;
+}
diff --git a/firmware/target/hosted/samsungypr/ypr1/mcs5000.h b/firmware/target/hosted/samsungypr/ypr1/mcs5000.h
new file mode 100644
index 0000000000..45cce19a32
--- /dev/null
+++ b/firmware/target/hosted/samsungypr/ypr1/mcs5000.h
@@ -0,0 +1,189 @@
+ /*
+ * Unfortunately I couldn't find any datasheet for this touch controller nor
+ * any other information. I tried to send Melfas an email but their servers
+ * seem to be full in this period. The best thing I could find is a Linux
+ * driver written by Samsung.
+ * In the opensource package for YP-R1 there are also some more information
+ * in the file r1TouchMelfasReg.h, which at the moment are not used (I2C stuff
+ * and error codes)
+ *
+ * The rest, function definitions, are written by me (Lorenzo Miori)
+ *
+ * mcs5000_ts.c - Touchscreen driver for MELFAS MCS-5000 controller
+ *
+ * Copyright (C) 2009 Samsung Electronics Co.Ltd
+ * Author: Joonyoung Shim <jy0922.shim@samsung.com>
+ *
+ * Based on wm97xx-core.c
+ *
+ * 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 is the wrapper to r1Touch.ko module with the possible
+ * ioctl calls
+ * The touchscreen controller is the Melfas MCS5000
+ */
+
+#define MCS5000_IOCTL_MAGIC 'X'
+
+#define MCS5000_IOCTL_TOUCH_RESET 0
+#define MCS5000_IOCTL_TOUCH_ON 1
+#define MCS5000_IOCTL_TOUCH_OFF 2
+#define MCS5000_IOCTL_TOUCH_FLUSH 3
+#define MCS5000_IOCTL_TOUCH_SLEEP 4
+#define MCS5000_IOCTL_TOUCH_WAKE 5
+#define MCS5000_IOCTL_TOUCH_ENTER_FWUPG_MODE 6
+#define MCS5000_IOCTL_TOUCH_I2C_READ 7
+#define MCS5000_IOCTL_TOUCH_I2C_WRITE 8
+#define MCS5000_IOCTL_TOUCH_RESET_AFTER_FWUPG 9
+#define MCS5000_IOCTL_TOUCH_RIGHTHAND 10
+#define MCS5000_IOCTL_TOUCH_LEFTHAND 11
+#define MCS5000_IOCTL_TOUCH_IDLE 12
+#define MCS5000_IOCTL_TOUCH_SET_SENSE 13
+#define MCS5000_IOCTL_TOUCH_GET_VER 14
+#define MCS5000_IOCTL_TOUCH_SET_REP_RATE 15
+#define MCS5000_IOCTL_TOUCH_ENABLE_WDOG 16
+#define MCS5000_IOCTL_TOUCH_DISABLE_WDOG 17
+
+struct mcs5000_i2c_data
+{
+ int count;
+ unsigned char addr;
+ unsigned char pData[256];
+} __attribute__((packed));
+
+#define DEV_CTRL_TOUCH_RESET _IO(MCS5000_IOCTL_MAGIC, MCS5000_IOCTL_TOUCH_RESET)
+#define DEV_CTRL_TOUCH_ON _IO(MCS5000_IOCTL_MAGIC, MCS5000_IOCTL_TOUCH_ON)
+#define DEV_CTRL_TOUCH_OFF _IO(MCS5000_IOCTL_MAGIC, MCS5000_IOCTL_TOUCH_OFF)
+#define DEV_CTRL_TOUCH_FLUSH _IO(MCS5000_IOCTL_MAGIC, MCS5000_IOCTL_TOUCH_FLUSH)
+#define DEV_CTRL_TOUCH_SLEEP _IO(MCS5000_IOCTL_MAGIC, MCS5000_IOCTL_TOUCH_SLEEP)
+#define DEV_CTRL_TOUCH_WAKE _IO(MCS5000_IOCTL_MAGIC, MCS5000_IOCTL_TOUCH_WAKE)
+#define DEV_CTRL_TOUCH_ENTER_FWUPG_MODE _IO(MCS5000_IOCTL_MAGIC, MCS5000_IOCTL_TOUCH_ENTER_FWUPG_MODE)
+#define DEV_CTRL_TOUCH_I2C_READ _IOWR(MCS5000_IOCTL_MAGIC, MCS5000_IOCTL_TOUCH_I2C_READ, mcs5000_i2c_data)
+#define DEV_CTRL_TOUCH_I2C_WRITE _IOWR(MCS5000_IOCTL_MAGIC, MCS5000_IOCTL_TOUCH_I2C_WRITE, mcs5000_i2c_data)
+#define DEV_CTRL_TOUCH_RESET_AFTER_FWUPG _IO(MCS5000_IOCTL_MAGIC, MCS5000_IOCTL_TOUCH_RESET_AFTER_FWUPG)
+#define DEV_CTRL_TOUCH_RIGHTHAND _IO(MCS5000_IOCTL_MAGIC, MCS5000_IOCTL_TOUCH_RIGHTHAND)
+#define DEV_CTRL_TOUCH_LEFTHAND _IO(MCS5000_IOCTL_MAGIC, MCS5000_IOCTL_TOUCH_LEFTHAND)
+#define DEV_CTRL_TOUCH_IDLE _IO(MCS5000_IOCTL_MAGIC, MCS5000_IOCTL_TOUCH_IDLE)
+#define DEV_CTRL_TOUCH_SET_SENSE _IOW(MCS5000_IOCTL_MAGIC, MCS5000_IOCTL_TOUCH_SET_SENSE, int)
+#define DEV_CTRL_TOUCH_GET_VER _IOR(MCS5000_IOCTL_MAGIC, MCS5000_IOCTL_TOUCH_GET_VER, int)
+#define DEV_CTRL_TOUCH_SET_REP_RATE _IOW(MCS5000_IOCTL_MAGIC, MCS5000_IOCTL_TOUCH_SET_REP_RATE, int)
+#define DEV_CTRL_TOUCH_ENABLE_WDOG _IO(MCS5000_IOCTL_MAGIC, MCS5000_IOCTL_TOUCH_ENABLE_WDOG)
+#define DEV_CTRL_TOUCH_DISABLE_WDOG _IO(MCS5000_IOCTL_MAGIC, MCS5000_IOCTL_TOUCH_DISABLE_WDOG)
+#define DEV_CTRL_TOUCH_MAX_NR 18
+
+/* Register definitions */
+#define MCS5000_TS_STATUS 0x00
+#define STATUS_OFFSET 0
+#define STATUS_NO (0 << STATUS_OFFSET)
+#define STATUS_INIT (1 << STATUS_OFFSET)
+#define STATUS_SENSING (2 << STATUS_OFFSET)
+#define STATUS_COORD (3 << STATUS_OFFSET)
+#define STATUS_GESTURE (4 << STATUS_OFFSET)
+#define ERROR_OFFSET 4
+#define ERROR_NO (0 << ERROR_OFFSET)
+#define ERROR_POWER_ON_RESET (1 << ERROR_OFFSET)
+#define ERROR_INT_RESET (2 << ERROR_OFFSET)
+#define ERROR_EXT_RESET (3 << ERROR_OFFSET)
+#define ERROR_INVALID_REG_ADDRESS (8 << ERROR_OFFSET)
+#define ERROR_INVALID_REG_VALUE (9 << ERROR_OFFSET)
+
+#define MCS5000_TS_OP_MODE 0x01
+#define RESET_OFFSET 0
+#define RESET_NO (0 << RESET_OFFSET)
+#define RESET_EXT_SOFT (1 << RESET_OFFSET)
+#define OP_MODE_OFFSET 1
+#define OP_MODE_SLEEP (0 << OP_MODE_OFFSET)
+#define OP_MODE_ACTIVE (1 << OP_MODE_OFFSET)
+#define GESTURE_OFFSET 4
+#define GESTURE_DISABLE (0 << GESTURE_OFFSET)
+#define GESTURE_ENABLE (1 << GESTURE_OFFSET)
+#define PROXIMITY_OFFSET 5
+#define PROXIMITY_DISABLE (0 << PROXIMITY_OFFSET)
+#define PROXIMITY_ENABLE (1 << PROXIMITY_OFFSET)
+#define SCAN_MODE_OFFSET 6
+#define SCAN_MODE_INTERRUPT (0 << SCAN_MODE_OFFSET)
+#define SCAN_MODE_POLLING (1 << SCAN_MODE_OFFSET)
+#define REPORT_RATE_OFFSET 7
+#define REPORT_RATE_40 (0 << REPORT_RATE_OFFSET)
+#define REPORT_RATE_80 (1 << REPORT_RATE_OFFSET)
+
+#define MCS5000_TS_SENS_CTL 0x02
+#define MCS5000_TS_FILTER_CTL 0x03
+#define PRI_FILTER_OFFSET 0
+#define SEC_FILTER_OFFSET 4
+
+#define MCS5000_TS_X_SIZE_UPPER 0x08
+#define MCS5000_TS_X_SIZE_LOWER 0x09
+#define MCS5000_TS_Y_SIZE_UPPER 0x0A
+#define MCS5000_TS_Y_SIZE_LOWER 0x0B
+
+#define MCS5000_TS_INPUT_INFO 0x10
+#define INPUT_TYPE_OFFSET 0
+#define INPUT_TYPE_NONTOUCH (0 << INPUT_TYPE_OFFSET)
+#define INPUT_TYPE_SINGLE (1 << INPUT_TYPE_OFFSET)
+#define INPUT_TYPE_DUAL (2 << INPUT_TYPE_OFFSET)
+#define INPUT_TYPE_PALM (3 << INPUT_TYPE_OFFSET)
+#define INPUT_TYPE_PROXIMITY (7 << INPUT_TYPE_OFFSET)
+#define GESTURE_CODE_OFFSET 3
+#define GESTURE_CODE_NO (0 << GESTURE_CODE_OFFSET)
+
+#define MCS5000_TS_X_POS_UPPER 0x11
+#define MCS5000_TS_X_POS_LOWER 0x12
+#define MCS5000_TS_Y_POS_UPPER 0x13
+#define MCS5000_TS_Y_POS_LOWER 0x14
+#define MCS5000_TS_Z_POS 0x15
+#define MCS5000_TS_WIDTH 0x16
+#define MCS5000_TS_GESTURE_VAL 0x17
+#define MCS5000_TS_MODULE_REV 0x20
+#define MCS5000_TS_FIRMWARE_VER 0x21
+
+/* Touchscreen absolute values */
+#define MCS5000_MAX_XC 0x3ff
+#define MCS5000_MAX_YC 0x3ff
+
+/* this struct also seems to have an alignment requirement (256-byte aligned?).
+ * touchscreen won't work correctly with 8-byte alignment. The aligned attribute
+ * cannot be attached here because it would make the struct larger and packed
+ * be ignored.
+ * See also mcs5000_read() */
+struct mcs5000_raw_data
+{
+ unsigned char inputInfo;
+ unsigned char xHigh;
+ unsigned char xLow;
+ unsigned char yHigh;
+ unsigned char yLow;
+ unsigned char z;
+ unsigned char width;
+ unsigned char gesture;
+} __attribute__((packed));
+
+/**
+ * Two possibilities for hand usage
+ */
+enum
+{
+ RIGHT_HAND,
+ LEFT_HAND,
+};
+
+/* Open device */
+void mcs5000_init(void);
+/* Close device */
+void mcs5000_close(void);
+/* Power up the chip (voltages) */
+void mcs5000_power(void);
+/* Shutdown the chip (voltages) */
+void mcs5000_shutdown(void);
+/* Set user hand usage */
+void mcs5000_set_hand(int hand_setting);
+/* Set touchscreen sensitivity. Valid values are 1,2,4,8 */
+void mcs5000_set_sensitivity(int level);
+/* Read controller's data */
+int mcs5000_read(struct mcs5000_raw_data *touchData);
diff --git a/firmware/target/hosted/samsungypr/ypr1/pmu-ypr1.c b/firmware/target/hosted/samsungypr/ypr1/pmu-ypr1.c
new file mode 100644
index 0000000000..8a2a724ca4
--- /dev/null
+++ b/firmware/target/hosted/samsungypr/ypr1/pmu-ypr1.c
@@ -0,0 +1,51 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ *
+ * Copyright (C) 2013 Lorenzo Miori
+ *
+ * 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 <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+#include "pmu-ypr1.h"
+#include "panic.h"
+
+static int pmu_dev = -1;
+
+void pmu_init(void)
+{
+ pmu_dev = open("/dev/r1Pmu", O_RDONLY);
+ if (pmu_dev < 0)
+ panicf("/dev/r1Pmu open error!");
+}
+
+void pmu_close(void)
+{
+ if (pmu_dev >= 0)
+ close(pmu_dev);
+}
+
+int pmu_get_dev(void)
+{
+ return pmu_dev;
+}
+
+int pmu_ioctl(int request, int *data)
+{
+ return ioctl(pmu_dev, request, data);
+}
diff --git a/firmware/target/hosted/samsungypr/ypr1/pmu-ypr1.h b/firmware/target/hosted/samsungypr/ypr1/pmu-ypr1.h
new file mode 100644
index 0000000000..e8103f22c9
--- /dev/null
+++ b/firmware/target/hosted/samsungypr/ypr1/pmu-ypr1.h
@@ -0,0 +1,88 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ *
+ * Copyright (C) 2013 Lorenzo Miori
+ *
+ * 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.
+ *
+ ****************************************************************************/
+
+#ifndef __PMU_YPR1_H__
+#define __PMU_YPR1_H__
+
+#include "sys/ioctl.h"
+
+/**
+ * This is the wrapper to r1Pmu.ko module with the possible
+ * ioctl calls
+ * The PMU controller is the MAX8819
+ */
+
+#define MAX8819_IOCTL_MAGIC 'A'
+
+#define E_MAX8819_IOCTL_GET_BATT_LVL 0
+#define E_MAX8819_IOCTL_GET_CHG_STATUS 1
+#define E_MAX8819_IOCTL_IS_EXT_PWR 2
+#define E_MAX8819_IOCTL_STOP_CHG 3
+#define E_MAX8819_IOCTL_START_CHG 4
+#define E_MAX8819_IOCTL_IS_EXT_PWR_OVP 5
+#define E_MAX8819_IOCTL_LCD_DIM_CTRL 6
+#define E_MAX8819_IOCTL_CORE_CTL_HIGH 7
+#define E_MAX8819_IOCTL_CORE_CTL_LOW 8
+#define E_MAX8819_IOCTL_TSP_USB_PWR_OFF 9
+
+#define MAX8819_IOCTL_GET_BATT_LVL _IO(MAX8819_IOCTL_MAGIC, E_MAX8819_IOCTL_GET_BATT_LVL)
+#define MAX8819_IOCTL_GET_CHG_STATUS _IO(MAX8819_IOCTL_MAGIC, E_MAX8819_IOCTL_GET_CHG_STATUS)
+#define MAX8819_IOCTL_IS_EXT_PWR _IO(MAX8819_IOCTL_MAGIC, E_MAX8819_IOCTL_IS_EXT_PWR)
+#define MAX8819_IOCTL_STOP_CHG _IO(MAX8819_IOCTL_MAGIC, E_MAX8819_IOCTL_STOP_CHG)
+#define MAX8819_IOCTL_START_CHG _IO(MAX8819_IOCTL_MAGIC, E_MAX8819_IOCTL_START_CHG)
+#define MAX8819_IOCTL_IS_EXT_PWR_OVP _IO(MAX8819_IOCTL_MAGIC, E_MAX8819_IOCTL_IS_EXT_PWR_OVP)
+#define MAX8819_IOCTL_LCD_DIM_CTRL _IOW(MAX8819_IOCTL_MAGIC, E_MAX8819_IOCTL_LCD_DIM_CTRL, int)
+#define MAX8819_IOCTL_CORE_CTL_HIGH _IO(MAX8819_IOCTL_MAGIC, E_MAX8819_IOCTL_CORE_CTL_HIGH)
+#define MAX8819_IOCTL_CORE_CTL_LOW _IO(MAX8819_IOCTL_MAGIC, E_MAX8819_IOCTL_CORE_CTL_LOW)
+#define MAX8819_IOCTL_TSP_USB_PWR_OFF _IO(MAX8819_IOCTL_MAGIC, E_MAX8819_IOCTL_TSP_USB_PWR_OFF)
+
+#define MAX8819_IOCTL_MAX_NR (E_MAX8819_IOCTL_TSP_USB_PWR_OFF+1)
+
+enum
+{
+ EXT_PWR_UNPLUGGED = 0,
+ EXT_PWR_PLUGGED,
+ EXT_PWR_NOT_OVP,
+ EXT_PWR_OVP,
+};
+
+enum
+{
+ PMU_CHARGING = 0,
+ PMU_NOT_CHARGING,
+ PMU_FULLY_CHARGED,
+};
+
+enum
+{
+ BATT_LVL_OFF = 0,
+ BATT_LVL_WARN,
+ BATT_LVL_1,
+ BATT_LVL_2,
+ BATT_LVL_3,
+ BATT_LVL_4,
+};
+
+void pmu_init(void);
+void pmu_close(void);
+int pmu_get_dev(void);
+int pmu_ioctl(int request, int *data);
+
+#endif
diff --git a/firmware/target/hosted/samsungypr/ypr1/powermgmt-ypr1.c b/firmware/target/hosted/samsungypr/ypr1/powermgmt-ypr1.c
new file mode 100644
index 0000000000..9a8f9747ae
--- /dev/null
+++ b/firmware/target/hosted/samsungypr/ypr1/powermgmt-ypr1.c
@@ -0,0 +1,153 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ *
+ * Copyright (C) 2013 Lorenzo Miori
+ *
+ * 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 "config.h"
+#include <sys/ioctl.h>
+#include "kernel.h"
+#include "powermgmt.h"
+#include "power.h"
+#include "file.h"
+#include "adc.h"
+#include "radio-ypr.h"
+#include "pmu-ypr1.h"
+#include "ioctl-ypr1.h"
+#include "stdio.h"
+#include "unistd.h"
+#include "fcntl.h"
+#include "system.h"
+
+#define MAX17040_VCELL 0x02
+#define MAX17040_SOC 0x04
+#define MAX17040_MODE 0x06
+#define MAX17040_VERSION 0x08
+#define MAX17040_RCOMP 0x0C
+#define MAX17040_COMMAND 0xFE
+
+static int max17040_dev = -1;
+
+void max17040_init(void)
+{
+ max17040_dev = open("/dev/r1Batt", O_RDONLY);
+ if (max17040_dev < 0)
+ printf("/dev/r1Batt open error!");
+}
+
+void max17040_close(void)
+{
+ if (max17040_dev >= 0)
+ close(max17040_dev);
+}
+
+#if (CONFIG_BATTERY_MEASURE & VOLTAGE_MEASURE) == VOLTAGE_MEASURE
+const unsigned short battery_level_dangerous[BATTERY_TYPES_COUNT] =
+{
+ 3470
+};
+
+/* the OF shuts down at this voltage */
+const unsigned short battery_level_shutoff[BATTERY_TYPES_COUNT] =
+{
+ 3450
+};
+
+/* voltages (millivolt) of 0%, 10%, ... 100% when charging disabled */
+const unsigned short percent_to_volt_discharge[BATTERY_TYPES_COUNT][11] =
+{
+ { 3450, 3502, 3550, 3587, 3623, 3669, 3742, 3836, 3926, 4026, 4200 }
+};
+#endif
+
+#if CONFIG_CHARGING
+/* voltages (millivolt) of 0%, 10%, ... 100% when charging enabled */
+const unsigned short const percent_to_volt_charge[11] =
+{
+ 3450, 3670, 3721, 3751, 3782, 3821, 3876, 3941, 4034, 4125, 4200
+};
+
+unsigned int power_input_status(void)
+{
+ unsigned status = POWER_INPUT_NONE;
+ if (pmu_ioctl(MAX8819_IOCTL_IS_EXT_PWR, NULL) > 0)
+ status = POWER_INPUT_MAIN_CHARGER;
+ return status;
+}
+
+#endif /* CONFIG_CHARGING */
+
+/* Returns battery voltage from MAX17040 VCELL ADC [millivolts steps],
+ * adc returns voltage in 1.25mV steps */
+/*
+ * TODO this would be interesting to be mixed with battery percentage, for information
+ * and completition purpouses
+ */
+#if (CONFIG_BATTERY_MEASURE & VOLTAGE_MEASURE) == VOLTAGE_MEASURE
+int _battery_voltage(void)
+{
+ int level = 4000;
+ max17040_request ret = { .addr = 2, .reg1 = 0, .reg2 = 0 };
+ if (ioctl(max17040_dev, MAX17040_READ_REG, &ret) >= 0)
+ {
+ int step = (ret.reg1 << 4) | (ret.reg2 >> 4);
+ level = step + (step >> 2);
+ }
+ return level;
+}
+#elif (CONFIG_BATTERY_MEASURE & PERCENTAGE_MEASURE) == PERCENTAGE_MEASURE
+int _battery_level(void)
+{
+ int level = 100;
+ max17040_request ret = { .addr = 4, .reg1 = 0, .reg2 = 0 };
+ if (ioctl(max17040_dev, MAX17040_READ_REG, &ret) >= 0)
+ level = MIN(ret.reg1, 100);
+ return level;
+}
+#endif
+
+bool charging_state(void)
+{
+ int ret = pmu_ioctl(MAX8819_IOCTL_GET_CHG_STATUS, NULL);
+ if (ret == PMU_FULLY_CHARGED)
+ return true;
+ return false;
+}
+
+#if CONFIG_TUNER
+static bool tuner_on = false;
+
+bool tuner_power(bool status)
+{
+ if (status != tuner_on)
+ {
+ tuner_on = status;
+ status = !status;
+ if (tuner_on)
+ radiodev_open();
+ else
+ radiodev_close();
+ }
+
+ return status;
+}
+
+bool tuner_powered(void)
+{
+ return tuner_on;
+}
+#endif /* #if CONFIG_TUNER */
diff --git a/firmware/target/hosted/samsungypr/ypr1/system-ypr1.c b/firmware/target/hosted/samsungypr/ypr1/system-ypr1.c
new file mode 100644
index 0000000000..d0cbddc55a
--- /dev/null
+++ b/firmware/target/hosted/samsungypr/ypr1/system-ypr1.c
@@ -0,0 +1,67 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ *
+ * Copyright (C) 2013 Lorenzo Miori
+ *
+ * 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 <stdlib.h>
+#include <string.h>
+#include <inttypes.h>
+#include "system.h"
+#include "panic.h"
+#include "debug.h"
+
+#include "gpio-target.h"
+#include "pmu-ypr1.h"
+#include "ioctl-ypr1.h"
+#include "audiohw.h"
+#include "button-target.h"
+
+void power_off(void)
+{
+ /* Something that we need to do before exit on our platform */
+ pmu_close();
+ max17040_close();
+ button_close_device();
+ gpio_close();
+ exit(EXIT_SUCCESS);
+}
+
+uintptr_t *stackbegin;
+uintptr_t *stackend;
+void system_init(void)
+{
+ int *s;
+ /* fake stack, OS manages size (and growth) */
+ stackbegin = stackend = (uintptr_t*)&s;
+
+ /* Here begins our platform specific initilization for various things */
+ audiohw_init();
+ gpio_init();
+ max17040_init();
+ pmu_init();
+}
+
+void system_reboot(void)
+{
+ power_off();
+}
+
+void system_exception_wait(void)
+{
+ system_reboot();
+}
diff --git a/firmware/target/hosted/samsungypr/ypr1/wmcodec-ypr1.c b/firmware/target/hosted/samsungypr/ypr1/wmcodec-ypr1.c
new file mode 100644
index 0000000000..f38c33ada1
--- /dev/null
+++ b/firmware/target/hosted/samsungypr/ypr1/wmcodec-ypr1.c
@@ -0,0 +1,90 @@
+/***************************************************************************
+ * __________ __ ___.
+ * Open \______ \ ____ ____ | | _\_ |__ _______ ___
+ * Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+ * Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+ * Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+ * \/ \/ \/ \/ \/
+ *
+ * I2C bus wrapper for WM1808 codec on SAMSUNG YP-R1
+ *
+ * Copyright (c) 2013 Lorenzo Miori
+ *
+ * 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 <stdio.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/ioctl.h>
+
+#include "system.h"
+#include "audiohw.h"
+#include "wmcodec.h"
+#include "audio.h"
+#include "panic.h"
+#include "logf.h"
+
+
+#define I2C_SLAVE 0x0703
+
+/**
+ * YP-R1's kernel has ALSA implementation of the WM1808, but it
+ * unfortunately doesn't export any function to play with register.
+ * For that reason we control the I2C bus directly, letting RB driver to do the rest
+ * Assumption: no other ALSA applications are using the mixer!
+ */
+
+static int wmcodec_dev = -1;
+
+/* The ONLY tested freq for now is 44100, others are just stubs!! */
+const struct wmc_srctrl_entry wmc_srctrl_table[HW_NUM_FREQ] =
+{
+ /* TODO fix PLL frequencies also for the other available rates */
+ [HW_FREQ_44] = /* PLL = on */
+ {
+ .plln = 3 | (1 << 3),
+ .pllk1 = 0x18, /* 11289600 */
+ .pllk2 = 0x111,
+ .pllk3 = 0x139,
+ .mclkdiv = WMC_MCLKDIV_2,
+ .filter = WMC_SR_48KHZ,
+ },
+};
+
+void audiohw_init(void)
+{
+ /* First of all we need to open the device */
+ wmcodec_dev = open("/dev/i2c-1", O_RDWR);
+ if (wmcodec_dev < 0)
+ panicf("Failed to open /dev/i2c-1 device!\n");
+
+ /* Let's set the slave address and if no error we are ready!*/
+ int addr = 0x1a;
+ if (ioctl(wmcodec_dev, I2C_SLAVE, addr) < 0)
+ logf("Failed to set slave address!\n");
+}
+
+void wmcodec_write(int reg, int data)
+{
+ unsigned char data2[2];
+ /* |aaaaaaad|dddddddd| */
+ data2[0] = (reg << 0x1) | ((data >> 8) & 0x1);
+ data2[1] = data;
+
+ if (write(wmcodec_dev, data2, 2) < 0)
+ panicf("I2C device write error!\n");
+}
+
+void audiohw_enable_headphone_jack(bool enable)
+{
+ /* We don't use this facility: we have a separate GPIO for that */
+ (void)enable;
+}
diff --git a/firmware/target/hosted/samsungypr/ypr1/ypr1.make b/firmware/target/hosted/samsungypr/ypr1/ypr1.make
new file mode 100644
index 0000000000..67ff326de0
--- /dev/null
+++ b/firmware/target/hosted/samsungypr/ypr1/ypr1.make
@@ -0,0 +1,24 @@
+# __________ __ ___.
+# Open \______ \ ____ ____ | | _\_ |__ _______ ___
+# Source | _// _ \_/ ___\| |/ /| __ \ / _ \ \/ /
+# Jukebox | | ( <_> ) \___| < | \_\ ( <_> > < <
+# Firmware |____|_ /\____/ \___ >__|_ \|___ /\____/__/\_ \
+# \/ \/ \/ \/ \/
+# $Id$
+#
+
+INCLUDES += -I$(FIRMDIR)/include -I$(FIRMDIR)/export $(TARGET_INC) -I$(BUILDDIR) -I$(APPSDIR)
+
+SIMFLAGS += $(INCLUDES) $(DEFINES) -DHAVE_CONFIG_H $(GCCOPTS)
+
+.SECONDEXPANSION: # $$(OBJ) is not populated until after this
+
+$(BUILDDIR)/rockbox.elf : $$(OBJ) $(FIRMLIB) $(VOICESPEEXLIB) $(CORE_LIBS)
+ $(call PRINTS,LD $(@F))$(CC) $(GCCOPTS) -Os -o $@ $(OBJ) \
+ -L$(BUILDDIR)/firmware -lfirmware \
+ -L$(RBCODEC_BLD)/codecs $(call a2lnk, $(VOICESPEEXLIB)) \
+ -L$(BUILDDIR)/lib $(call a2lnk,$(CORE_LIBS)) \
+ $(LDOPTS) $(GLOBAL_LDOPTS) -Wl,-Map,$(BUILDDIR)/rockbox.map
+
+$(BUILDDIR)/rockbox : $(BUILDDIR)/rockbox.elf
+ $(call PRINTS,OC $(@F))$(call objcopy,$^,$@)