Index: firmware/export/config/samsungypr0.h
===================================================================
--- firmware/export/config/samsungypr0.h	(revision 31528)
+++ firmware/export/config/samsungypr0.h	(working copy)
@@ -119,8 +119,8 @@
 /* #define CONFIG_TUNER SI4700 */
 /* #define HAVE_TUNER_PWR_CTRL*/
 
-/*TODO: In R0 there is an interrupt for this (figure out ioctls)*/
-/* #define HAVE_HEADPHONE_DETECTION */
+/* We have a GPIO that detects it */
+#define HAVE_HEADPHONE_DETECTION
 
 #define BATTERY_CAPACITY_DEFAULT 600 /* default battery capacity */
 #define BATTERY_CAPACITY_MIN 600  /* min. capacity selectable */
Index: firmware/SOURCES
===================================================================
--- firmware/SOURCES	(revision 31528)
+++ firmware/SOURCES	(working copy)
@@ -82,6 +82,7 @@
 #endif
 target/hosted/ypr0/ascodec-ypr0.c
 target/hosted/ypr0/powermgmt-ypr0.c
+target/hosted/ypr0/gpio_ypr0.c
 #endif
 
 /* Maemo specific files */
Index: firmware/target/hosted/ypr0/r0GPIOIoctl.h
===================================================================
--- firmware/target/hosted/ypr0/r0GPIOIoctl.h	(revision 0)
+++ firmware/target/hosted/ypr0/r0GPIOIoctl.h	(revision 0)
@@ -0,0 +1,185 @@
+/* This file originates from the linux kernel provided in Samsung's YP-R0 Open
+ * Source package (second release, which includes some driver modules sources).
+ */
+
+#ifndef __IOCTL_GPIO_H__
+#define __IOCTL_GPIO_H__
+
+#include <sys/ioctl.h>
+//#include "iomux.h"
+
+typedef struct {
+	int num;
+	int mode;
+	int val;
+}__attribute__((packed)) R0GPIOInfo;
+
+
+#define IOCTL_GPIO_MAGIC 	'G'
+
+#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, R0GPIOInfo)
+#define DEV_CTRL_GPIO_UNSET_MUX		_IOW(IOCTL_GPIO_MAGIC, 1, R0GPIOInfo)
+#define DEV_CTRL_GPIO_SET_TYPE		_IOW(IOCTL_GPIO_MAGIC, 2, R0GPIOInfo)
+#define DEV_CTRL_GPIO_SET_OUTPUT	_IOW(IOCTL_GPIO_MAGIC, 3, R0GPIOInfo)
+#define DEV_CTRL_GPIO_SET_INPUT		_IOW(IOCTL_GPIO_MAGIC, 4, R0GPIOInfo)
+#define DEV_CTRL_GPIO_SET_HIGH		_IOW(IOCTL_GPIO_MAGIC, 5, R0GPIOInfo)
+#define DEV_CTRL_GPIO_SET_LOW		_IOW(IOCTL_GPIO_MAGIC, 6, R0GPIOInfo)
+#define DEV_CTRL_GPIO_GET_VAL		_IOW(IOCTL_GPIO_MAGIC, 7, R0GPIOInfo)
+#define DEV_CTRL_GPIO_IS_HIGH		_IOW(IOCTL_GPIO_MAGIC, 8, R0GPIOInfo)
+
+
+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 /* __IOCTL_GPIO__H__ */
Index: firmware/target/hosted/ypr0/button-ypr0.c
===================================================================
--- firmware/target/hosted/ypr0/button-ypr0.c	(revision 31528)
+++ firmware/target/hosted/ypr0/button-ypr0.c	(working copy)
@@ -28,6 +28,7 @@
 #include "kernel.h"
 #include "system.h"
 #include "button-target.h"
+#include <gpio_ypr0.h> /* For headphones sense */
 
 /* R0 physical key codes */
 enum ypr0_buttons {
@@ -45,6 +46,7 @@
 
 
 static int r0_btn_fd = 0;
+
 /* Samsung keypad driver doesn't allow multiple key combinations :( */
 static enum ypr0_buttons r0_read_key(void)
 {
@@ -82,6 +84,11 @@
     return key_to_button(r0_read_key());
 }
 
+bool headphones_inserted(void)
+{
+    /* GPIO low - 0 - means headphones inserted */
+    return (gpio_control(DEV_CTRL_GPIO_IS_HIGH, GPIO_HEADPHONE_SENSE, 0, 0) == 1) ? false : true;
+}
 
 /* Open the keypad device: it is offered by r0Btn.ko module */
 void button_init_device(void)
@@ -89,6 +96,10 @@
     r0_btn_fd = open("/dev/r0Btn", O_RDONLY);
     if (r0_btn_fd < 0)
         printf("/dev/r0Btn open error!");
+
+    /* Setup GPIO pin for headphone sense, copied from OF */
+    gpio_control(DEV_CTRL_GPIO_SET_MUX, GPIO_HEADPHONE_SENSE, CONFIG_SION, PAD_CTL_47K_PU);
+    gpio_control(DEV_CTRL_GPIO_SET_INPUT, GPIO_HEADPHONE_SENSE, CONFIG_SION, PAD_CTL_47K_PU);
 }
 
 #ifdef BUTTON_DRIVER_CLOSE
@@ -99,5 +110,8 @@
         close(r0_btn_fd);
         printf("/dev/r0Btn closed!");
     }
+    /* Don't know the precise meaning, but it's done as in the OF, so copied there */
+    gpio_control(DEV_CTRL_GPIO_UNSET_MUX, GPIO_HEADPHONE_SENSE, CONFIG_SION, 0);
+    
 }
 #endif /* BUTTON_DRIVER_CLOSE */
Index: firmware/target/hosted/ypr0/button-target.h
===================================================================
--- firmware/target/hosted/ypr0/button-target.h	(revision 31528)
+++ firmware/target/hosted/ypr0/button-target.h	(working copy)
@@ -5,7 +5,7 @@
  *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
  *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
  *                     \/            \/     \/    \/            \/
- * $Id: button-target.h 29248 2011-02-08 20:05:25Z thomasjfox $
+ * $Id$
  *
  * Copyright (C) 2011 by Lorenzo Miori
  *
@@ -25,6 +25,8 @@
 #include <stdbool.h>
 #include "config.h"
 
+bool headphones_inserted(void);
+
 void button_init_device(void);
 void button_close_device(void);
 int button_read_device(void);
Index: firmware/target/hosted/ypr0/gpio_ypr0.c
===================================================================
--- firmware/target/hosted/ypr0/gpio_ypr0.c	(revision 0)
+++ firmware/target/hosted/ypr0/gpio_ypr0.c	(revision 0)
@@ -0,0 +1,54 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id: ascodec-target.h 26116 2010-05-17 20:53:25Z funman $
+ *
+ * Module wrapper for GPIO, using /dev/r0GPIO (r0Gpio.ko) of Samsung YP-R0
+ *
+ * Copyright (c) 2011 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 <gpio_ypr0.h> /* includes r0GPIOioctl.h */
+#include <sys/ioctl.h>
+
+static int r0_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!");
+}
+
+void gpio_close(void)
+{
+    if (r0_gpio_dev < 0)
+        close(r0_gpio_dev);
+}
+
+int gpio_control_struct(int request, R0GPIOInfo r)
+{
+    return ioctl(r0_gpio_dev, request, &r);
+}
+
+int gpio_control(int request, int num, int mode, int val)
+{
+    R0GPIOInfo r = { .num = num, .mode = mode, .val = val, };
+    return ioctl(r0_gpio_dev, request, &r);
+}
\ No newline at end of file
Index: firmware/target/hosted/ypr0/system-ypr0.c
===================================================================
--- firmware/target/hosted/ypr0/system-ypr0.c	(revision 31528)
+++ firmware/target/hosted/ypr0/system-ypr0.c	(working copy)
@@ -31,11 +31,13 @@
 #endif
 
 #include "ascodec-target.h"
+#include "gpio_ypr0.h"
 
 void power_off(void)
 {
     /* Something that we need to do before exit on our platform YPR0 */
     ascodec_close();
+    gpio_close();
     exit(EXIT_SUCCESS);
 }
 
@@ -52,6 +54,7 @@
 #endif
     /* Here begins our platform specific initilization for various things */
     ascodec_init();
+    gpio_init();
 }
 
 
Index: firmware/target/hosted/ypr0/gpio_ypr0.h
===================================================================
--- firmware/target/hosted/ypr0/gpio_ypr0.h	(revision 0)
+++ firmware/target/hosted/ypr0/gpio_ypr0.h	(revision 0)
@@ -0,0 +1,42 @@
+/***************************************************************************
+ *             __________               __   ___.
+ *   Open      \______   \ ____   ____ |  | _\_ |__   _______  ___
+ *   Source     |       _//  _ \_/ ___\|  |/ /| __ \ /  _ \  \/  /
+ *   Jukebox    |    |   (  <_> )  \___|    < | \_\ (  <_> > <  <
+ *   Firmware   |____|_  /\____/ \___  >__|_ \|___  /\____/__/\_ \
+ *                     \/            \/     \/    \/            \/
+ * $Id: ascodec-target.h 26116 2010-05-17 20:53:25Z funman $
+ *
+ * Module wrapper for GPIO, using /dev/r0GPIO (r0Gpio.ko) of Samsung YP-R0
+ *
+ * Copyright (c) 2011 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_YPR0_H
+#define GPIO_YPR0_H
+
+#include "r0GPIOIoctl.h"
+
+/* Some meaningful pins used in the R0 */
+
+#define GPIO_HEADPHONE_SENSE          GPIO1_5
+//26
+#define GPIO_EXT_PWR_SENSE            GPIO1_26
+//59
+#define GPIO_SD_SENSE                 GPIO2_24
+
+void gpio_init(void);
+void gpio_close(void);
+int gpio_control_struct(int request, R0GPIOInfo pin);
+int gpio_control(int request, int num, int mode, int val);
+
+#endif
\ No newline at end of file
