diff --git a/firmware/SOURCES b/firmware/SOURCES index a52f01494d..0143b9c2d5 100644 --- a/firmware/SOURCES +++ b/firmware/SOURCES @@ -82,6 +82,7 @@ target/hosted/ypr0/backlight-ypr0.c #endif target/hosted/ypr0/ascodec-ypr0.c target/hosted/ypr0/powermgmt-ypr0.c +target/hosted/ypr0/gpio_ypr0.c #endif /* Maemo specific files */ diff --git a/firmware/export/config/samsungypr0.h b/firmware/export/config/samsungypr0.h index 53b9285ac4..2de36dcb74 100644 --- a/firmware/export/config/samsungypr0.h +++ b/firmware/export/config/samsungypr0.h @@ -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 */ diff --git a/firmware/target/hosted/ypr0/button-target.h b/firmware/target/hosted/ypr0/button-target.h index 5d65d97607..beddc66c67 100644 --- a/firmware/target/hosted/ypr0/button-target.h +++ b/firmware/target/hosted/ypr0/button-target.h @@ -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 #include "config.h" +bool headphones_inserted(void); + void button_init_device(void); void button_close_device(void); int button_read_device(void); diff --git a/firmware/target/hosted/ypr0/button-ypr0.c b/firmware/target/hosted/ypr0/button-ypr0.c index 4298410161..5953bcebf9 100644 --- a/firmware/target/hosted/ypr0/button-ypr0.c +++ b/firmware/target/hosted/ypr0/button-ypr0.c @@ -28,6 +28,7 @@ #include "kernel.h" #include "system.h" #include "button-target.h" +#include /* For headphones sense */ /* R0 physical key codes */ enum ypr0_buttons { @@ -45,6 +46,7 @@ enum ypr0_buttons { 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 @@ int button_read_device(void) 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); +} /* Open the keypad device: it is offered by r0Btn.ko module */ void button_init_device(void) @@ -89,6 +96,10 @@ void button_init_device(void) 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,7 @@ void button_close_device(void) 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 */ diff --git a/firmware/target/hosted/ypr0/gpio_ypr0.c b/firmware/target/hosted/ypr0/gpio_ypr0.c new file mode 100644 index 0000000000..9c3f186a6b --- /dev/null +++ b/firmware/target/hosted/ypr0/gpio_ypr0.c @@ -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 +#include +#include +#include /* includes r0GPIOioctl.h */ +#include + +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 diff --git a/firmware/target/hosted/ypr0/gpio_ypr0.h b/firmware/target/hosted/ypr0/gpio_ypr0.h new file mode 100644 index 0000000000..9fc7444887 --- /dev/null +++ b/firmware/target/hosted/ypr0/gpio_ypr0.h @@ -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 diff --git a/firmware/target/hosted/ypr0/r0GPIOIoctl.h b/firmware/target/hosted/ypr0/r0GPIOIoctl.h new file mode 100644 index 0000000000..e77f35fbb7 --- /dev/null +++ b/firmware/target/hosted/ypr0/r0GPIOIoctl.h @@ -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 +//#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__ */ diff --git a/firmware/target/hosted/ypr0/system-ypr0.c b/firmware/target/hosted/ypr0/system-ypr0.c index bf3b1cd4c9..784b4fe48e 100644 --- a/firmware/target/hosted/ypr0/system-ypr0.c +++ b/firmware/target/hosted/ypr0/system-ypr0.c @@ -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 @@ void system_init(void) #endif /* Here begins our platform specific initilization for various things */ ascodec_init(); + gpio_init(); }