1/* 2 * arch/ubicom32/mach-ip7k/board-ip7160dpf.c 3 * Platform initialization for ip7160dpf board. 4 * 5 * (C) Copyright 2009, Ubicom, Inc. 6 * 7 * This file is part of the Ubicom32 Linux Kernel Port. 8 * 9 * The Ubicom32 Linux Kernel Port is free software: you can redistribute 10 * it and/or modify it under the terms of the GNU General Public License 11 * as published by the Free Software Foundation, either version 2 of the 12 * License, or (at your option) any later version. 13 * 14 * The Ubicom32 Linux Kernel Port is distributed in the hope that it 15 * will be useful, but WITHOUT ANY WARRANTY; without even the implied 16 * warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See 17 * the GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with the Ubicom32 Linux Kernel Port. If not, 21 * see <http://www.gnu.org/licenses/>. 22 * 23 * Ubicom32 implementation derived from (with many thanks): 24 * arch/m68knommu 25 * arch/blackfin 26 * arch/parisc 27 */ 28#include <linux/device.h> 29#include <linux/platform_device.h> 30#include <linux/delay.h> 31#include <linux/gpio.h> 32 33#include <linux/i2c.h> 34#include <linux/i2c-gpio.h> 35 36#include <linux/input.h> 37 38#include <asm/board.h> 39#include <asm/machdep.h> 40#include <asm/ubicom32hid.h> 41#include <asm/vdc_tio.h> 42#include <asm/audio.h> 43 44/* 45 * Backlight on the board PD0, hardware PWM 46 */ 47static const struct ubicom32hid_button ip7160dpf_ubicom32hid_buttons[] = { 48 { 49 .type = EV_KEY, 50 .code = KEY_UP, 51 .bit = 0, 52 }, 53 { 54 .type = EV_KEY, 55 .code = KEY_LEFT, 56 .bit = 1, 57 }, 58 { 59 .type = EV_KEY, 60 .code = KEY_RIGHT, 61 .bit = 2, 62 }, 63 { 64 .type = EV_KEY, 65 .code = KEY_DOWN, 66 .bit = 3, 67 }, 68 { 69 .type = EV_KEY, 70 .code = KEY_ENTER, 71 .bit = 4, 72 }, 73 { 74 .type = EV_KEY, 75 .code = KEY_MENU, 76 .bit = 5, 77 }, 78 { 79 .type = EV_KEY, 80 .code = KEY_ESC, 81 .bit = 7, 82 }, 83}; 84 85static const struct ubicom32hid_ir ip7160dpf_ubicom32hid_ircodes[] = { 86 { 87 .type = EV_KEY, 88 .code = KEY_UP, 89 .ir_code = 0xF807916E 90 }, 91 { 92 .type = EV_KEY, 93 .code = KEY_DOWN, 94 .ir_code = 0xF20D916E 95 }, 96 { 97 .type = EV_KEY, 98 .code = KEY_LEFT, 99 .ir_code = 0xF609916E 100 }, 101 { 102 .type = EV_KEY, 103 .code = KEY_RIGHT, 104 .ir_code = 0xF40B916E 105 }, 106 { 107 .type = EV_KEY, 108 .code = KEY_ENTER, 109 .ir_code = 0xF50A916E 110 }, 111 { /* rotate */ 112 .type = EV_KEY, 113 .code = KEY_FN_F1, 114 .ir_code = 0xF906916E 115 }, 116 { 117 .type = EV_KEY, 118 .code = KEY_MENU, 119 .ir_code = 0xF708916E 120 }, 121 { /* font size */ 122 .type = EV_KEY, 123 .code = KEY_FN_F2, 124 .ir_code = 0xF30C916E 125 }, 126 { 127 .type = EV_KEY, 128 .code = KEY_ESC, 129 .ir_code = 0xF10E916E 130 }, 131 { 132 .type = EV_KEY, 133 .code = KEY_VOLUMEUP, 134 .ir_code = 0xF00F916E 135 }, 136 { 137 .type = EV_KEY, 138 .code = KEY_VOLUMEDOWN, 139 .ir_code = 0xED12916E 140 }, 141 { 142 .type = EV_KEY, 143 .code = KEY_MUTE, 144 .ir_code = 0xEA15916E 145 }, 146 { 147 .type = EV_KEY, 148 .code = KEY_INFO, 149 .ir_code = 0xEF10916E 150 }, 151 { /* Like */ 152 .type = EV_KEY, 153 .code = KEY_FN_F3, 154 .ir_code = 0xEE11916E 155 }, 156 { /* Dislike */ 157 .type = EV_KEY, 158 .code = KEY_FN_F4, 159 .ir_code = 0xEB14916E 160 }, 161 { 162 .type = EV_KEY, 163 .code = KEY_POWER, 164 .ir_code = 0xFD02916E 165 }, 166}; 167 168static struct ubicom32hid_platform_data ip7160dpf_ubicom32hid_platform_data = { 169 .gpio_reset = GPIO_RI_5, 170 .gpio_reset_polarity = 0, 171 .type = UBICOM32HID_BL_TYPE_PWM, 172 .invert = 0, 173 .default_intensity = 128, 174 .buttons = ip7160dpf_ubicom32hid_buttons, 175 .nbuttons = ARRAY_SIZE(ip7160dpf_ubicom32hid_buttons), 176 .ircodes = ip7160dpf_ubicom32hid_ircodes, 177 .nircodes = ARRAY_SIZE(ip7160dpf_ubicom32hid_ircodes), 178}; 179 180/* 181 * Devices on the I2C bus 182 * This board has a "bus 2" which is isolated from the main bus by U47 183 * and pin RI0. It should be safe to always enable bus 2 by setting 184 * RI0 to low, however, it should be noted that on all existing configurations 185 * of this board, U49 and U51 are not populated. 186 */ 187static struct i2c_board_info __initdata ip7160dpf_i2c_board_info[] = { 188 /* 189 * U37, CS4350 DAC, address 0x4B, bus 2 190 * THIS ENTRY MUST BE FIRST 191 */ 192 { 193 .type = "cs4350", 194 .addr = 0x4B, 195 } 196 197 /* 198 * U24, ubicom32hid 199 */ 200 { 201 .type = "ubicom32hid", 202 .addr = 0x08, 203 .platform_data = &ip7160dpf_ubicom32hid_platform_data, 204 }, 205 206 /* 207 * U49, ISL29001 Ambient Light Sensor, address 0x44, bus 2 (may not be stuffed) 208 */ 209 210 /* 211 * U51, S35390A RTC, address 0x30, bus 2 (may not be stuffed) 212 */ 213#ifdef CONFIG_RTC_DRV_S35390A 214 { 215 .type = "s35390a", 216 .addr = 0x30, 217 }, 218#endif 219}; 220 221/* 222 * I2C bus on the board, SDA PI1, SCL PI2 223 */ 224static struct i2c_gpio_platform_data ip7160dpf_i2c_data = { 225 .sda_pin = GPIO_RI_1, 226 .scl_pin = GPIO_RI_2, 227 .sda_is_open_drain = 0, 228 .scl_is_open_drain = 0, 229 .scl_is_output_only = 1, 230 .udelay = 6, 231}; 232 233static struct platform_device ip7160dpf_i2c_device = { 234 .name = "i2c-gpio", 235 .id = 0, 236 .dev = { 237 .platform_data = &ip7160dpf_i2c_data, 238 }, 239}; 240 241/* 242 * List of all devices in our system 243 */ 244static struct platform_device *ip7160dpf_devices[] __initdata = { 245 &ip7160dpf_i2c_device, 246}; 247 248/* 249 * ip7160dpf_power_off 250 * Called to turn the power off for this board 251 */ 252static void ip7160dpf_power_off(void) 253{ 254 gpio_set_value(GPIO_RF_14, 0); 255} 256 257/* 258 * ip7160dpf_init 259 * Called to add the devices which we have on this board 260 */ 261static int __init ip7160dpf_init(void) 262{ 263 int ret; 264 struct platform_device *audio_dev; 265 266 ubi_gpio_init(); 267 268 /* 269 * Hold the POWER_HOLD line 270 */ 271 ret = gpio_request(GPIO_RF_14, "POWER_HOLD"); 272 if (ret) { 273 printk(KERN_ERR "%s: could not request POWER_HOLD GPIO\n", __FUNCTION__); 274 } 275 gpio_direction_output(GPIO_RF_14, 1); 276 mach_power_off = ip7160dpf_power_off; 277 278 /* 279 * USB SEL_HOST_USB line 280 */ 281 ret = gpio_request(GPIO_RI_13, "SEL_HOST_USB"); 282 if (ret) { 283 printk(KERN_ERR "%s: could not request SEL_HOST_USB GPIO\n", __FUNCTION__); 284 } 285 gpio_direction_output(GPIO_RI_13, 0); 286 287 /* 288 * USB/DAC nRESET line 289 */ 290 ret = gpio_request(GPIO_RI_3, "USB_DAC_nRESET"); 291 if (ret) { 292 printk(KERN_ERR "%s: could not request USB_DAC_nRESET GPIO\n", __FUNCTION__); 293 } 294 gpio_direction_output(GPIO_RI_3, 0); 295 udelay(1); 296 gpio_direction_output(GPIO_RI_3, 1); 297 298 /* 299 * I2C BUS2 Disable line 300 */ 301 ret = gpio_request(GPIO_RI_0, "DISABLE_BUS2"); 302 if (ret) { 303 printk(KERN_ERR "%s: could not request DISABLE_BUS2 GPIO\n", __FUNCTION__); 304 } 305 gpio_direction_output(GPIO_RI_0, 0); 306 307 vdc_tio_init(); 308 309 printk(KERN_INFO "%s: registering device resources\n", __FUNCTION__); 310 platform_add_devices(ip7160dpf_devices, ARRAY_SIZE(ip7160dpf_devices)); 311 312 /* 313 * Allocate the audio driver if we can 314 */ 315 audio_dev = audio_device_alloc("snd-ubi32-cs4350", "audio-i2sout", 0); 316 if (audio_dev) { 317 ip7160dpf_i2c_board_info[0].platform_data = audio_dev; 318 } 319 320 printk(KERN_INFO "%s: registering i2c resources\n", __FUNCTION__); 321 i2c_register_board_info(0, ip7160dpf_i2c_board_info, ARRAY_SIZE(ip7160dpf_i2c_board_info)); 322 323 return 0; 324} 325 326arch_initcall(ip7160dpf_init); 327