Ying-Chun Liu (PaulLiu) | 21e9f4c | 2011-06-10 10:39:43 +0800 | [diff] [blame] | 1 | /* |
| 2 | * da9052-gpio.c -- GPIO Driver for Dialog DA9052 |
| 3 | * |
| 4 | * Copyright(c) 2009 Dialog Semiconductor Ltd. |
| 5 | * |
| 6 | * Author: Dialog Semiconductor Ltd <dchen@diasemi.com> |
| 7 | * |
| 8 | * This program is free software; you can redistribute it and/or modify it |
| 9 | * under the terms of the GNU General Public License as published by the |
| 10 | * Free Software Foundation; either version 2 of the License, or (at your |
| 11 | * option) any later version. |
| 12 | * |
| 13 | */ |
| 14 | |
| 15 | #include <linux/module.h> |
| 16 | #include <linux/fs.h> |
| 17 | #include <linux/uaccess.h> |
| 18 | #include <linux/platform_device.h> |
| 19 | #include <linux/syscalls.h> |
| 20 | #include <linux/seq_file.h> |
| 21 | #include <linux/gpio.h> |
| 22 | |
| 23 | #include <linux/mfd/da9052/da9052.h> |
| 24 | #include <linux/mfd/da9052/reg.h> |
| 25 | #include <linux/mfd/da9052/gpio.h> |
| 26 | |
| 27 | #define DRIVER_NAME "da9052-gpio" |
| 28 | static inline struct da9052_gpio_chip *to_da9052_gpio(struct gpio_chip *chip) |
| 29 | { |
| 30 | return container_of(chip, struct da9052_gpio_chip, gp); |
| 31 | } |
| 32 | |
| 33 | void da9052_gpio_notifier(struct da9052_eh_nb *eh_data, unsigned int event) |
| 34 | { |
| 35 | struct da9052_gpio_chip *gpio = |
| 36 | container_of(eh_data, struct da9052_gpio_chip, eh_data); |
| 37 | kobject_uevent(&gpio->gp.dev->kobj, KOBJ_CHANGE); |
| 38 | printk(KERN_INFO "Event received from GPIO8\n"); |
| 39 | } |
| 40 | |
| 41 | static u8 create_gpio_config_value(u8 gpio_function, u8 gpio_type, u8 gpio_mode) |
| 42 | { |
| 43 | /* The format is - |
| 44 | function - 2 bits |
| 45 | type - 1 bit |
| 46 | mode - 1 bit */ |
| 47 | return gpio_function | (gpio_type << 2) | (gpio_mode << 3); |
| 48 | } |
| 49 | |
| 50 | static s32 write_default_gpio_values(struct da9052 *da9052) |
| 51 | { |
| 52 | struct da9052_ssc_msg msg; |
| 53 | u8 created_val = 0; |
| 54 | |
| 55 | #if (DA9052_GPIO_PIN_0 == DA9052_GPIO_CONFIG) |
| 56 | da9052_lock(da9052); |
| 57 | msg.addr = DA9052_GPIO0001_REG; |
| 58 | msg.data = 0; |
| 59 | |
| 60 | if (da9052->read(da9052, &msg)) { |
| 61 | da9052_unlock(da9052); |
| 62 | return -EIO; |
| 63 | } |
| 64 | |
| 65 | created_val = create_gpio_config_value(DEFAULT_GPIO0_FUNCTION, |
| 66 | DEFAULT_GPIO0_TYPE, DEFAULT_GPIO0_MODE); |
| 67 | msg.data &= DA9052_GPIO_MASK_UPPER_NIBBLE; |
| 68 | msg.data |= created_val; |
| 69 | |
| 70 | if (da9052->write(da9052, &msg)) { |
| 71 | da9052_unlock(da9052); |
| 72 | return -EIO; |
| 73 | } |
| 74 | da9052_unlock(da9052); |
| 75 | #endif |
| 76 | #if (DA9052_GPIO_PIN_1 == DA9052_GPIO_CONFIG) |
| 77 | da9052_lock(da9052); |
| 78 | msg.addr = DA9052_GPIO0001_REG; |
| 79 | msg.data = 0; |
| 80 | |
| 81 | if (da9052->read(da9052, &msg)) { |
| 82 | da9052_unlock(da9052); |
| 83 | return -EIO; |
| 84 | } |
| 85 | |
| 86 | created_val = create_gpio_config_value(DEFAULT_GPIO1_FUNCTION, |
| 87 | DEFAULT_GPIO1_TYPE, DEFAULT_GPIO1_MODE); |
| 88 | created_val = created_val << DA9052_GPIO_NIBBLE_SHIFT; |
| 89 | msg.data &= DA9052_GPIO_MASK_LOWER_NIBBLE; |
| 90 | msg.data |= created_val; |
| 91 | |
| 92 | if (da9052->write(da9052, &msg)) { |
| 93 | da9052_unlock(da9052); |
| 94 | return -EIO; |
| 95 | } |
| 96 | da9052_unlock(da9052); |
| 97 | #endif |
| 98 | /* GPIO 2-3*/ |
| 99 | #if (DA9052_GPIO_PIN_2 == DA9052_GPIO_CONFIG) |
| 100 | da9052_lock(da9052); |
| 101 | msg.addr = DA9052_GPIO0203_REG; |
| 102 | msg.data = 0; |
| 103 | |
| 104 | if (da9052->read(da9052, &msg)) { |
| 105 | da9052_unlock(da9052); |
| 106 | return -EIO; |
| 107 | } |
| 108 | |
| 109 | created_val = create_gpio_config_value(DEFAULT_GPIO2_FUNCTION, |
| 110 | DEFAULT_GPIO2_TYPE, DEFAULT_GPIO2_MODE); |
| 111 | msg.data &= DA9052_GPIO_MASK_UPPER_NIBBLE; |
| 112 | msg.data |= created_val; |
| 113 | |
| 114 | if (da9052->write(da9052, &msg)) { |
| 115 | da9052_unlock(da9052); |
| 116 | return -EIO; |
| 117 | } |
| 118 | da9052_unlock(da9052); |
| 119 | #endif |
| 120 | #if (DA9052_GPIO_PIN_3 == DA9052_GPIO_CONFIG) |
| 121 | da9052_lock(da9052); |
| 122 | msg.addr = DA9052_GPIO0203_REG; |
| 123 | msg.data = 0; |
| 124 | |
| 125 | if (da9052->read(da9052, &msg)) { |
| 126 | da9052_unlock(da9052); |
| 127 | return -EIO; |
| 128 | } |
| 129 | |
| 130 | created_val = create_gpio_config_value(DEFAULT_GPIO3_FUNCTION, |
| 131 | DEFAULT_GPIO3_TYPE, DEFAULT_GPIO3_MODE); |
| 132 | created_val = created_val << DA9052_GPIO_NIBBLE_SHIFT; |
| 133 | msg.data &= DA9052_GPIO_MASK_LOWER_NIBBLE; |
| 134 | msg.data |= created_val; |
| 135 | |
| 136 | if (da9052->write(da9052, &msg)) { |
| 137 | da9052_unlock(da9052); |
| 138 | return -EIO; |
| 139 | } |
| 140 | da9052_unlock(da9052); |
| 141 | #endif |
| 142 | /* GPIO 4-5*/ |
| 143 | #if (DA9052_GPIO_PIN_4 == DA9052_GPIO_CONFIG) |
| 144 | da9052_lock(da9052); |
| 145 | msg.addr = DA9052_GPIO0405_REG; |
| 146 | msg.data = 0; |
| 147 | |
| 148 | if (da9052->read(da9052, &msg)) { |
| 149 | da9052_unlock(da9052); |
| 150 | return -EIO; |
| 151 | } |
| 152 | |
| 153 | created_val = create_gpio_config_value(DEFAULT_GPIO4_FUNCTION, |
| 154 | DEFAULT_GPIO4_TYPE, DEFAULT_GPIO4_MODE); |
| 155 | msg.data &= DA9052_GPIO_MASK_UPPER_NIBBLE; |
| 156 | msg.data |= created_val; |
| 157 | |
| 158 | if (da9052->write(da9052, &msg)) { |
| 159 | da9052_unlock(da9052); |
| 160 | return -EIO; |
| 161 | } |
| 162 | da9052_unlock(da9052); |
| 163 | #endif |
| 164 | #if (DA9052_GPIO_PIN_5 == DA9052_GPIO_CONFIG) |
| 165 | da9052_lock(da9052); |
| 166 | msg.addr = DA9052_GPIO0405_REG; |
| 167 | msg.data = 0; |
| 168 | |
| 169 | if (da9052->read(da9052, &msg)) { |
| 170 | da9052_unlock(da9052); |
| 171 | return -EIO; |
| 172 | } |
| 173 | |
| 174 | created_val = create_gpio_config_value(DEFAULT_GPIO5_FUNCTION, |
| 175 | DEFAULT_GPIO5_TYPE, DEFAULT_GPIO5_MODE); |
| 176 | created_val = created_val << DA9052_GPIO_NIBBLE_SHIFT; |
| 177 | msg.data &= DA9052_GPIO_MASK_LOWER_NIBBLE; |
| 178 | msg.data |= created_val; |
| 179 | |
| 180 | if (da9052->write(da9052, &msg)) { |
| 181 | da9052_unlock(da9052); |
| 182 | return -EIO; |
| 183 | } |
| 184 | da9052_unlock(da9052); |
| 185 | #endif |
| 186 | /* GPIO 6-7*/ |
| 187 | #if (DA9052_GPIO_PIN_6 == DA9052_GPIO_CONFIG) |
| 188 | da9052_lock(da9052); |
| 189 | msg.addr = DA9052_GPIO0607_REG; |
| 190 | msg.data = 0; |
| 191 | |
| 192 | if (da9052->read(da9052, &msg)) { |
| 193 | da9052_unlock(da9052); |
| 194 | return -EIO; |
| 195 | } |
| 196 | |
| 197 | created_val = create_gpio_config_value(DEFAULT_GPIO6_FUNCTION, |
| 198 | DEFAULT_GPIO6_TYPE, DEFAULT_GPIO6_MODE); |
| 199 | msg.data &= DA9052_GPIO_MASK_UPPER_NIBBLE; |
| 200 | msg.data |= created_val; |
| 201 | |
| 202 | if (da9052->write(da9052, &msg)) { |
| 203 | da9052_unlock(da9052); |
| 204 | return -EIO; |
| 205 | } |
| 206 | da9052_unlock(da9052); |
| 207 | #endif |
| 208 | #if (DA9052_GPIO_PIN_7 == DA9052_GPIO_CONFIG) |
| 209 | da9052_lock(da9052); |
| 210 | msg.addr = DA9052_GPIO0607_REG; |
| 211 | msg.data = 0; |
| 212 | |
| 213 | if (da9052->read(da9052, &msg)) { |
| 214 | da9052_unlock(da9052); |
| 215 | return -EIO; |
| 216 | } |
| 217 | |
| 218 | created_val = create_gpio_config_value(DEFAULT_GPIO7_FUNCTION, |
| 219 | DEFAULT_GPIO7_TYPE, DEFAULT_GPIO7_MODE); |
| 220 | created_val = created_val << DA9052_GPIO_NIBBLE_SHIFT; |
| 221 | msg.data &= DA9052_GPIO_MASK_LOWER_NIBBLE; |
| 222 | msg.data |= created_val; |
| 223 | |
| 224 | if (da9052->write(da9052, &msg)) { |
| 225 | da9052_unlock(da9052); |
| 226 | return -EIO; |
| 227 | } |
| 228 | da9052_unlock(da9052); |
| 229 | #endif |
| 230 | /* GPIO 8-9*/ |
| 231 | #if (DA9052_GPIO_PIN_8 == DA9052_GPIO_CONFIG) |
| 232 | da9052_lock(da9052); |
| 233 | msg.addr = DA9052_GPIO0809_REG; |
| 234 | msg.data = 0; |
| 235 | if (da9052->read(da9052, &msg)) { |
| 236 | da9052_unlock(da9052); |
| 237 | return -EIO; |
| 238 | } |
| 239 | |
| 240 | created_val = create_gpio_config_value(DEFAULT_GPIO8_FUNCTION, |
| 241 | DEFAULT_GPIO8_TYPE, DEFAULT_GPIO8_MODE); |
| 242 | msg.data &= DA9052_GPIO_MASK_UPPER_NIBBLE; |
| 243 | msg.data |= created_val; |
| 244 | |
| 245 | if (da9052->write(da9052, &msg)) { |
| 246 | da9052_unlock(da9052); |
| 247 | return -EIO; |
| 248 | } |
| 249 | da9052_unlock(da9052); |
| 250 | #endif |
| 251 | #if (DA9052_GPIO_PIN_9 == DA9052_GPIO_CONFIG) |
| 252 | da9052_lock(da9052); |
| 253 | msg.addr = DA9052_GPIO0809_REG; |
| 254 | msg.data = 0; |
| 255 | |
| 256 | if (da9052->read(da9052, &msg)) { |
| 257 | da9052_unlock(da9052); |
| 258 | return -EIO; |
| 259 | } |
| 260 | |
| 261 | created_val = create_gpio_config_value(DEFAULT_GPIO9_FUNCTION, |
| 262 | DEFAULT_GPIO9_TYPE, DEFAULT_GPIO9_MODE); |
| 263 | created_val = created_val << DA9052_GPIO_NIBBLE_SHIFT; |
| 264 | msg.data &= DA9052_GPIO_MASK_LOWER_NIBBLE; |
| 265 | msg.data |= created_val; |
| 266 | |
| 267 | if (da9052->write(da9052, &msg)) { |
| 268 | da9052_unlock(da9052); |
| 269 | return -EIO; |
| 270 | } |
| 271 | da9052_unlock(da9052); |
| 272 | #endif |
| 273 | /* GPIO 10-11*/ |
| 274 | #if (DA9052_GPIO_PIN_10 == DA9052_GPIO_CONFIG) |
| 275 | da9052_lock(da9052); |
| 276 | msg.addr = DA9052_GPIO1011_REG; |
| 277 | msg.data = 0; |
| 278 | |
| 279 | if (da9052->read(da9052, &msg)) { |
| 280 | da9052_unlock(da9052); |
| 281 | return -EIO; |
| 282 | } |
| 283 | |
| 284 | created_val = create_gpio_config_value(DEFAULT_GPIO10_FUNCTION, |
| 285 | DEFAULT_GPIO10_TYPE, DEFAULT_GPIO10_MODE); |
| 286 | msg.data &= DA9052_GPIO_MASK_UPPER_NIBBLE; |
| 287 | msg.data |= created_val; |
| 288 | |
| 289 | if (da9052->write(da9052, &msg)) { |
| 290 | da9052_unlock(da9052); |
| 291 | return -EIO; |
| 292 | } |
| 293 | da9052_unlock(da9052); |
| 294 | #endif |
| 295 | #if (DA9052_GPIO_PIN_11 == DA9052_GPIO_CONFIG) |
| 296 | da9052_lock(da9052); |
| 297 | msg.addr = DA9052_GPIO1011_REG; |
| 298 | msg.data = 0; |
| 299 | |
| 300 | if (da9052->read(da9052, &msg)) { |
| 301 | da9052_unlock(da9052); |
| 302 | return -EIO; |
| 303 | } |
| 304 | |
| 305 | created_val = create_gpio_config_value(DEFAULT_GPIO11_FUNCTION, |
| 306 | DEFAULT_GPIO11_TYPE, DEFAULT_GPIO11_MODE); |
| 307 | created_val = created_val << DA9052_GPIO_NIBBLE_SHIFT; |
| 308 | msg.data &= DA9052_GPIO_MASK_LOWER_NIBBLE; |
| 309 | msg.data |= created_val; |
| 310 | |
| 311 | if (da9052->write(da9052, &msg)) { |
| 312 | da9052_unlock(da9052); |
| 313 | return -EIO; |
| 314 | } |
| 315 | da9052_unlock(da9052); |
| 316 | #endif |
| 317 | /* GPIO 12-13*/ |
| 318 | #if (DA9052_GPIO_PIN_12 == DA9052_GPIO_CONFIG) |
| 319 | da9052_lock(da9052); |
| 320 | msg.addr = DA9052_GPIO1213_REG; |
| 321 | msg.data = 0; |
| 322 | |
| 323 | if (da9052->read(da9052, &msg)) { |
| 324 | da9052_unlock(da9052); |
| 325 | return -EIO; |
| 326 | } |
| 327 | |
| 328 | created_val = create_gpio_config_value(DEFAULT_GPIO12_FUNCTION, |
| 329 | DEFAULT_GPIO12_TYPE, DEFAULT_GPIO12_MODE); |
| 330 | msg.data &= DA9052_GPIO_MASK_UPPER_NIBBLE; |
| 331 | msg.data |= created_val; |
| 332 | |
| 333 | if (da9052->write(da9052, &msg)) { |
| 334 | da9052_unlock(da9052); |
| 335 | return -EIO; |
| 336 | } |
| 337 | da9052_unlock(da9052); |
| 338 | #endif |
| 339 | #if (DA9052_GPIO_PIN_13 == DA9052_GPIO_CONFIG) |
| 340 | da9052_lock(da9052); |
| 341 | msg.addr = DA9052_GPIO1213_REG; |
| 342 | msg.data = 0; |
| 343 | |
| 344 | if (da9052->read(da9052, &msg)) { |
| 345 | da9052_unlock(da9052); |
| 346 | return -EIO; |
| 347 | } |
| 348 | |
| 349 | created_val = create_gpio_config_value(DEFAULT_GPIO13_FUNCTION, |
| 350 | DEFAULT_GPIO13_TYPE, DEFAULT_GPIO13_MODE); |
| 351 | created_val = created_val << DA9052_GPIO_NIBBLE_SHIFT; |
| 352 | msg.data &= DA9052_GPIO_MASK_LOWER_NIBBLE; |
| 353 | msg.data |= created_val; |
| 354 | |
| 355 | if (da9052->write(da9052, &msg)) { |
| 356 | da9052_unlock(da9052); |
| 357 | return -EIO; |
| 358 | } |
| 359 | da9052_unlock(da9052); |
| 360 | #endif |
| 361 | /* GPIO 14-15*/ |
| 362 | #if (DA9052_GPIO_PIN_14 == DA9052_GPIO_CONFIG) |
| 363 | da9052_lock(da9052); |
| 364 | msg.addr = DA9052_GPIO1415_REG; |
| 365 | msg.data = 0; |
| 366 | |
| 367 | if (da9052->read(da9052, &msg)) { |
| 368 | da9052_unlock(da9052); |
| 369 | return -EIO; |
| 370 | } |
| 371 | |
| 372 | created_val = create_gpio_config_value(DEFAULT_GPIO14_FUNCTION, |
| 373 | DEFAULT_GPIO14_TYPE, DEFAULT_GPIO14_MODE); |
| 374 | msg.data &= DA9052_GPIO_MASK_UPPER_NIBBLE; |
| 375 | msg.data |= created_val; |
| 376 | |
| 377 | if (da9052->write(da9052, &msg)) { |
| 378 | da9052_unlock(da9052); |
| 379 | return -EIO; |
| 380 | } |
| 381 | da9052_unlock(da9052); |
| 382 | #endif |
| 383 | #if (DA9052_GPIO_PIN_15 == DA9052_GPIO_CONFIG) |
| 384 | da9052_lock(da9052); |
| 385 | msg.addr = DA9052_GPIO1415_REG; |
| 386 | msg.data = 0; |
| 387 | |
| 388 | if (da9052->read(da9052, &msg)) { |
| 389 | da9052_unlock(da9052); |
| 390 | return -EIO; |
| 391 | } |
| 392 | |
| 393 | created_val = create_gpio_config_value(DEFAULT_GPIO15_FUNCTION, |
| 394 | DEFAULT_GPIO15_TYPE, DEFAULT_GPIO15_MODE); |
| 395 | created_val = created_val << DA9052_GPIO_NIBBLE_SHIFT; |
| 396 | msg.data &= DA9052_GPIO_MASK_LOWER_NIBBLE; |
| 397 | msg.data |= created_val; |
| 398 | |
| 399 | if (da9052->write(da9052, &msg)) { |
| 400 | da9052_unlock(da9052); |
| 401 | return -EIO; |
| 402 | } |
| 403 | da9052_unlock(da9052); |
| 404 | #endif |
| 405 | return 0; |
| 406 | } |
| 407 | |
| 408 | s32 da9052_gpio_read_port(struct da9052_gpio_read_write *read_port, |
| 409 | struct da9052 *da9052) |
| 410 | { |
| 411 | struct da9052_ssc_msg msg; |
| 412 | u8 shift_value = 0; |
| 413 | u8 port_functionality = 0; |
| 414 | msg.addr = (read_port->port_number / 2) + DA9052_GPIO0001_REG; |
| 415 | msg.data = 0; |
| 416 | da9052_lock(da9052); |
| 417 | if (da9052->read(da9052, &msg)) { |
| 418 | da9052_unlock(da9052); |
| 419 | return -EIO; |
| 420 | } |
| 421 | da9052_unlock(da9052); |
| 422 | port_functionality = |
| 423 | (read_port->port_number % 2) ? |
| 424 | ((msg.data & DA9052_GPIO_ODD_PORT_FUNCTIONALITY) >> |
| 425 | DA9052_GPIO_NIBBLE_SHIFT) : |
| 426 | (msg.data & DA9052_GPIO_EVEN_PORT_FUNCTIONALITY); |
| 427 | |
| 428 | if (port_functionality != INPUT) |
| 429 | return DA9052_GPIO_INVALID_PORTNUMBER; |
| 430 | |
| 431 | if (read_port->port_number >= (DA9052_GPIO_MAX_PORTNUMBER)) |
| 432 | return DA9052_GPIO_INVALID_PORTNUMBER; |
| 433 | |
| 434 | if (read_port->port_number < DA9052_GPIO_MAX_PORTS_PER_REGISTER) |
| 435 | msg.addr = DA9052_STATUSC_REG; |
| 436 | else |
| 437 | msg.addr = DA9052_STATUSD_REG; |
| 438 | msg.data = 0; |
| 439 | |
| 440 | da9052_lock(da9052); |
| 441 | if (da9052->read(da9052, &msg)) { |
| 442 | da9052_unlock(da9052); |
| 443 | return -EIO; |
| 444 | } |
| 445 | da9052_unlock(da9052); |
| 446 | |
| 447 | shift_value = msg.data & |
| 448 | (1 << DA9052_GPIO_SHIFT_COUNT(read_port->port_number)); |
| 449 | read_port->read_write_value = (shift_value >> |
| 450 | DA9052_GPIO_SHIFT_COUNT(read_port->port_number)); |
| 451 | |
| 452 | return 0; |
| 453 | } |
| 454 | |
| 455 | s32 da9052_gpio_multiple_read(struct da9052_gpio_multiple_read *multiple_port, |
| 456 | struct da9052 *da9052) |
| 457 | { |
| 458 | struct da9052_ssc_msg msg[2]; |
| 459 | u8 port_number = 0; |
| 460 | u8 loop_index = 0; |
| 461 | msg[loop_index++].addr = DA9052_STATUSC_REG; |
| 462 | msg[loop_index++].addr = DA9052_STATUSD_REG; |
| 463 | |
| 464 | da9052_lock(da9052); |
| 465 | if (da9052->read_many(da9052, msg, loop_index)) { |
| 466 | da9052_unlock(da9052); |
| 467 | return -EIO; |
| 468 | } |
| 469 | da9052_unlock(da9052); |
| 470 | loop_index = 0; |
| 471 | for (port_number = 0; port_number < DA9052_GPIO_MAX_PORTS_PER_REGISTER; |
| 472 | port_number++) { |
| 473 | multiple_port->signal_value[port_number] = |
| 474 | msg[loop_index].data & 1; |
| 475 | msg[loop_index].data = msg[loop_index].data >> 1; |
| 476 | } |
| 477 | loop_index++; |
| 478 | for (port_number = DA9052_GPIO_MAX_PORTS_PER_REGISTER; |
| 479 | port_number < DA9052_GPIO_MAX_PORTNUMBER; port_number++) { |
| 480 | multiple_port->signal_value[port_number] = |
| 481 | msg[loop_index].data & 1; |
| 482 | msg[loop_index].data = msg[loop_index].data >> 1; |
| 483 | } |
| 484 | return 0; |
| 485 | } |
| 486 | EXPORT_SYMBOL(da9052_gpio_multiple_read); |
| 487 | |
| 488 | s32 da9052_gpio_write_port(struct da9052_gpio_read_write *write_port, |
| 489 | struct da9052 *da9052) |
| 490 | { |
| 491 | struct da9052_ssc_msg msg; |
| 492 | u8 port_functionality = 0; |
| 493 | u8 bit_pos = 0; |
| 494 | msg.addr = DA9052_GPIO0001_REG + (write_port->port_number / 2); |
| 495 | msg.data = 0; |
| 496 | |
| 497 | da9052_lock(da9052); |
| 498 | if (da9052->read(da9052, &msg)) { |
| 499 | da9052_unlock(da9052); |
| 500 | return -EIO; |
| 501 | } |
| 502 | da9052_unlock(da9052); |
| 503 | |
| 504 | port_functionality = |
| 505 | (write_port->port_number % 2) ? |
| 506 | ((msg.data & DA9052_GPIO_ODD_PORT_FUNCTIONALITY) >> |
| 507 | DA9052_GPIO_NIBBLE_SHIFT) : |
| 508 | (msg.data & DA9052_GPIO_EVEN_PORT_FUNCTIONALITY); |
| 509 | |
| 510 | if (port_functionality < 2) |
| 511 | return DA9052_GPIO_INVALID_PORTNUMBER; |
| 512 | |
| 513 | bit_pos = (write_port->port_number % 2) ? |
| 514 | DA9052_GPIO_ODD_PORT_WRITE_MODE : |
| 515 | DA9052_GPIO_EVEN_PORT_WRITE_MODE; |
| 516 | |
| 517 | if (write_port->read_write_value) |
| 518 | msg.data = msg.data | bit_pos; |
| 519 | else |
| 520 | msg.data = (msg.data & ~(bit_pos)); |
| 521 | |
| 522 | da9052_lock(da9052); |
| 523 | if (da9052->write(da9052, &msg)) { |
| 524 | da9052_unlock(da9052); |
| 525 | return -EIO; |
| 526 | } |
| 527 | da9052_unlock(da9052); |
| 528 | return 0; |
| 529 | } |
| 530 | |
| 531 | s32 da9052_gpio_configure_port(struct da9052_gpio *gpio_data, |
| 532 | struct da9052 *da9052) |
| 533 | { |
| 534 | struct da9052_ssc_msg msg; |
| 535 | u8 register_value = 0; |
| 536 | u8 function = 0; |
| 537 | u8 port_functionality = 0; |
| 538 | msg.addr = (gpio_data->port_number / 2) + DA9052_GPIO0001_REG; |
| 539 | msg.data = 0; |
| 540 | |
| 541 | da9052_lock(da9052); |
| 542 | if (da9052->read(da9052, &msg)) { |
| 543 | da9052_unlock(da9052); |
| 544 | return -EIO; |
| 545 | } |
| 546 | da9052_unlock(da9052); |
| 547 | |
| 548 | port_functionality = |
| 549 | (gpio_data->port_number % 2) ? |
| 550 | ((msg.data & DA9052_GPIO_ODD_PORT_FUNCTIONALITY) >> |
| 551 | DA9052_GPIO_NIBBLE_SHIFT) : |
| 552 | (msg.data & DA9052_GPIO_EVEN_PORT_FUNCTIONALITY); |
| 553 | if (port_functionality < INPUT) |
| 554 | return DA9052_GPIO_INVALID_PORTNUMBER; |
| 555 | if (gpio_data->gpio_config.input.type > ACTIVE_HIGH) |
| 556 | return DA9052_GPIO_INVALID_TYPE; |
| 557 | if (gpio_data->gpio_config.input.mode > DEBOUNCING_ON) |
| 558 | return DA9052_GPIO_INVALID_MODE; |
| 559 | function = gpio_data->gpio_function; |
| 560 | switch (function) { |
| 561 | case INPUT: |
| 562 | register_value = create_gpio_config_value(function, |
| 563 | gpio_data->gpio_config.input.type, |
| 564 | gpio_data->gpio_config.input.mode); |
| 565 | break; |
| 566 | case OUTPUT_OPENDRAIN: |
| 567 | case OUTPUT_PUSHPULL: |
| 568 | register_value = create_gpio_config_value(function, |
| 569 | gpio_data->gpio_config.input.type, |
| 570 | gpio_data->gpio_config.input.mode); |
| 571 | break; |
| 572 | default: |
| 573 | return DA9052_GPIO_INVALID_FUNCTION; |
| 574 | break; |
| 575 | } |
| 576 | |
| 577 | if (gpio_data->port_number % 2) { |
| 578 | msg.data = (msg.data & ~(DA9052_GPIO_MASK_UPPER_NIBBLE)) | |
| 579 | (register_value << DA9052_GPIO_NIBBLE_SHIFT); |
| 580 | } else { |
| 581 | msg.data = (msg.data & ~(DA9052_GPIO_MASK_LOWER_NIBBLE)) | |
| 582 | register_value; |
| 583 | } |
| 584 | da9052_lock(da9052); |
| 585 | if (da9052->write(da9052, &msg)) { |
| 586 | da9052_unlock(da9052); |
| 587 | return -EIO; |
| 588 | } |
| 589 | da9052_unlock(da9052); |
| 590 | return 0; |
| 591 | } |
| 592 | |
| 593 | static s32 da9052_gpio_read(struct gpio_chip *gc, u32 offset) |
| 594 | { |
| 595 | struct da9052_gpio_chip *gpio; |
| 596 | gpio = to_da9052_gpio(gc); |
| 597 | gpio->read_write.port_number = offset; |
| 598 | da9052_gpio_read_port(&gpio->read_write, gpio->da9052); |
| 599 | return gpio->read_write.read_write_value; |
| 600 | } |
| 601 | |
| 602 | static void da9052_gpio_write(struct gpio_chip *gc, u32 offset, s32 value) |
| 603 | { |
| 604 | struct da9052_gpio_chip *gpio; |
| 605 | gpio = to_da9052_gpio(gc); |
| 606 | gpio->read_write.port_number = offset; |
| 607 | gpio->read_write.read_write_value = (u8)value; |
| 608 | da9052_gpio_write_port(&gpio->read_write, gpio->da9052); |
| 609 | } |
| 610 | |
| 611 | static s32 da9052_gpio_ip(struct gpio_chip *gc, u32 offset) |
| 612 | { |
| 613 | struct da9052_gpio_chip *gpio; |
| 614 | gpio = to_da9052_gpio(gc); |
| 615 | gpio->gpio.gpio_function = INPUT; |
| 616 | gpio->gpio.gpio_config.input.type = ACTIVE_LOW; |
| 617 | gpio->gpio.gpio_config.input.mode = DEBOUNCING_ON; |
| 618 | gpio->gpio.port_number = offset; |
| 619 | return da9052_gpio_configure_port(&gpio->gpio, gpio->da9052); |
| 620 | } |
| 621 | |
| 622 | static s32 da9052_gpio_op(struct gpio_chip *gc, u32 offset, s32 value) |
| 623 | { |
| 624 | struct da9052_gpio_chip *gpio; |
| 625 | gpio = to_da9052_gpio(gc); |
| 626 | gpio->gpio.gpio_function = OUTPUT_PUSHPULL; |
| 627 | gpio->gpio.gpio_config.output.type = SUPPLY_VDD_IO1; |
| 628 | gpio->gpio.gpio_config.output.mode = value; |
| 629 | gpio->gpio.port_number = offset; |
| 630 | return da9052_gpio_configure_port(&gpio->gpio, gpio->da9052); |
| 631 | } |
| 632 | |
| 633 | static int da9052_gpio_to_irq(struct gpio_chip *gc, u32 offset) |
| 634 | { |
| 635 | struct da9052_gpio_chip *gpio; |
| 636 | gpio = to_da9052_gpio(gc); |
| 637 | kobject_uevent(&gpio->gp.dev->kobj, KOBJ_CHANGE); |
| 638 | printk(KERN_INFO"gpio->gp.base +offset = %d\n", gpio->gp.base + offset); |
| 639 | printk(KERN_INFO"Test1\n\n"); |
| 640 | return gpio->gp.base + offset; |
| 641 | } |
| 642 | |
| 643 | static int __devinit da9052_gpio_probe(struct platform_device *pdev) |
| 644 | { |
| 645 | struct da9052_gpio_chip *gpio; |
| 646 | struct da9052_platform_data *pdata = (pdev->dev.platform_data); |
| 647 | s32 ret; |
| 648 | gpio = kzalloc(sizeof(*gpio), GFP_KERNEL); |
| 649 | if (gpio == NULL) |
| 650 | return -ENOMEM; |
| 651 | gpio->da9052 = dev_get_drvdata(pdev->dev.parent); |
| 652 | gpio->gp.get = da9052_gpio_read; |
| 653 | gpio->gp.direction_input = da9052_gpio_ip; |
| 654 | gpio->gp.direction_output = da9052_gpio_op; |
| 655 | gpio->gp.set = da9052_gpio_write; |
| 656 | |
| 657 | gpio->gp.base = pdata->gpio_base; |
| 658 | gpio->gp.ngpio = DA9052_GPIO_MAX_PORTNUMBER; |
| 659 | gpio->gp.can_sleep = 1; |
| 660 | gpio->gp.dev = &pdev->dev; |
| 661 | gpio->gp.owner = THIS_MODULE; |
| 662 | gpio->gp.label = "da9052-gpio"; |
| 663 | gpio->gp.to_irq = da9052_gpio_to_irq; |
| 664 | |
| 665 | gpio->eh_data.eve_type = GPI8_EVE; |
| 666 | gpio->eh_data.call_back = &da9052_gpio_notifier; |
| 667 | ret = gpio->da9052->register_event_notifier(gpio->da9052, |
| 668 | &gpio->eh_data); |
| 669 | |
| 670 | ret = write_default_gpio_values(gpio->da9052); |
| 671 | if (ret < 0) { |
| 672 | dev_err(&pdev->dev, "GPIO initial config failed, %d\n", |
| 673 | ret); |
| 674 | goto ret; |
| 675 | } |
| 676 | |
| 677 | ret = gpiochip_add(&gpio->gp); |
| 678 | if (ret < 0) { |
| 679 | dev_err(&pdev->dev, "Could not register gpiochip, %d\n", |
| 680 | ret); |
| 681 | goto ret; |
| 682 | } |
| 683 | platform_set_drvdata(pdev, gpio); |
| 684 | |
| 685 | return ret; |
| 686 | |
| 687 | ret: |
| 688 | kfree(gpio); |
| 689 | return ret; |
| 690 | |
| 691 | } |
| 692 | |
| 693 | static int __devexit da9052_gpio_remove(struct platform_device *pdev) |
| 694 | { |
| 695 | struct da9052_gpio_chip *gpio = platform_get_drvdata(pdev); |
| 696 | int ret; |
| 697 | |
| 698 | gpio->da9052->unregister_event_notifier |
| 699 | (gpio->da9052, &gpio->eh_data); |
| 700 | ret = gpiochip_remove(&gpio->gp); |
| 701 | if (ret == 0) |
| 702 | kfree(gpio); |
| 703 | return 0; |
| 704 | } |
| 705 | |
| 706 | static struct platform_driver da9052_gpio_driver = { |
| 707 | .probe = da9052_gpio_probe, |
| 708 | .remove = __devexit_p(da9052_gpio_remove), |
| 709 | .driver = { |
| 710 | .name = DRIVER_NAME, |
| 711 | .owner = THIS_MODULE, |
| 712 | }, |
| 713 | }; |
| 714 | |
| 715 | static int __init da9052_gpio_init(void) |
| 716 | { |
| 717 | return platform_driver_register(&da9052_gpio_driver); |
| 718 | } |
| 719 | |
| 720 | static void __exit da9052_gpio_exit(void) |
| 721 | { |
| 722 | return platform_driver_unregister(&da9052_gpio_driver); |
| 723 | } |
| 724 | |
| 725 | module_init(da9052_gpio_init); |
| 726 | module_exit(da9052_gpio_exit); |
| 727 | |
| 728 | MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>"); |
| 729 | MODULE_DESCRIPTION("DA9052 GPIO Device Driver"); |
| 730 | MODULE_LICENSE("GPL"); |
| 731 | MODULE_ALIAS("platform:" DRIVER_NAME); |