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