1/* 2 * Nano River Technologies viperboard GPIO lib driver 3 * 4 * (C) 2012 by Lemonage GmbH 5 * Author: Lars Poeschel <poeschel@lemonage.de> 6 * All rights reserved. 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/kernel.h> 16#include <linux/errno.h> 17#include <linux/module.h> 18#include <linux/slab.h> 19#include <linux/types.h> 20#include <linux/mutex.h> 21#include <linux/platform_device.h> 22 23#include <linux/usb.h> 24#include <linux/gpio.h> 25 26#include <linux/mfd/viperboard.h> 27 28#define VPRBRD_GPIOA_CLK_1MHZ 0 29#define VPRBRD_GPIOA_CLK_100KHZ 1 30#define VPRBRD_GPIOA_CLK_10KHZ 2 31#define VPRBRD_GPIOA_CLK_1KHZ 3 32#define VPRBRD_GPIOA_CLK_100HZ 4 33#define VPRBRD_GPIOA_CLK_10HZ 5 34 35#define VPRBRD_GPIOA_FREQ_DEFAULT 1000 36 37#define VPRBRD_GPIOA_CMD_CONT 0x00 38#define VPRBRD_GPIOA_CMD_PULSE 0x01 39#define VPRBRD_GPIOA_CMD_PWM 0x02 40#define VPRBRD_GPIOA_CMD_SETOUT 0x03 41#define VPRBRD_GPIOA_CMD_SETIN 0x04 42#define VPRBRD_GPIOA_CMD_SETINT 0x05 43#define VPRBRD_GPIOA_CMD_GETIN 0x06 44 45#define VPRBRD_GPIOB_CMD_SETDIR 0x00 46#define VPRBRD_GPIOB_CMD_SETVAL 0x01 47 48struct vprbrd_gpioa_msg { 49 u8 cmd; 50 u8 clk; 51 u8 offset; 52 u8 t1; 53 u8 t2; 54 u8 invert; 55 u8 pwmlevel; 56 u8 outval; 57 u8 risefall; 58 u8 answer; 59 u8 __fill; 60} __packed; 61 62struct vprbrd_gpiob_msg { 63 u8 cmd; 64 u16 val; 65 u16 mask; 66} __packed; 67 68struct vprbrd_gpio { 69 struct gpio_chip gpioa; /* gpio a related things */ 70 u32 gpioa_out; 71 u32 gpioa_val; 72 struct gpio_chip gpiob; /* gpio b related things */ 73 u32 gpiob_out; 74 u32 gpiob_val; 75 struct vprbrd *vb; 76}; 77 78/* gpioa sampling clock module parameter */ 79static unsigned char gpioa_clk; 80static unsigned int gpioa_freq = VPRBRD_GPIOA_FREQ_DEFAULT; 81module_param(gpioa_freq, uint, 0); 82MODULE_PARM_DESC(gpioa_freq, 83 "gpio-a sampling freq in Hz (default is 1000Hz) valid values: 10, 100, 1000, 10000, 100000, 1000000"); 84 85/* ----- begin of gipo a chip -------------------------------------------- */ 86 87static int vprbrd_gpioa_get(struct gpio_chip *chip, 88 unsigned offset) 89{ 90 int ret, answer, error = 0; 91 struct vprbrd_gpio *gpio = 92 container_of(chip, struct vprbrd_gpio, gpioa); 93 struct vprbrd *vb = gpio->vb; 94 struct vprbrd_gpioa_msg *gamsg = (struct vprbrd_gpioa_msg *)vb->buf; 95 96 /* if io is set to output, just return the saved value */ 97 if (gpio->gpioa_out & (1 << offset)) 98 return gpio->gpioa_val & (1 << offset); 99 100 mutex_lock(&vb->lock); 101 102 gamsg->cmd = VPRBRD_GPIOA_CMD_GETIN; 103 gamsg->clk = 0x00; 104 gamsg->offset = offset; 105 gamsg->t1 = 0x00; 106 gamsg->t2 = 0x00; 107 gamsg->invert = 0x00; 108 gamsg->pwmlevel = 0x00; 109 gamsg->outval = 0x00; 110 gamsg->risefall = 0x00; 111 gamsg->answer = 0x00; 112 gamsg->__fill = 0x00; 113 114 ret = usb_control_msg(vb->usb_dev, usb_sndctrlpipe(vb->usb_dev, 0), 115 VPRBRD_USB_REQUEST_GPIOA, VPRBRD_USB_TYPE_OUT, 0x0000, 116 0x0000, gamsg, sizeof(struct vprbrd_gpioa_msg), 117 VPRBRD_USB_TIMEOUT_MS); 118 if (ret != sizeof(struct vprbrd_gpioa_msg)) 119 error = -EREMOTEIO; 120 121 ret = usb_control_msg(vb->usb_dev, usb_rcvctrlpipe(vb->usb_dev, 0), 122 VPRBRD_USB_REQUEST_GPIOA, VPRBRD_USB_TYPE_IN, 0x0000, 123 0x0000, gamsg, sizeof(struct vprbrd_gpioa_msg), 124 VPRBRD_USB_TIMEOUT_MS); 125 answer = gamsg->answer & 0x01; 126 127 mutex_unlock(&vb->lock); 128 129 if (ret != sizeof(struct vprbrd_gpioa_msg)) 130 error = -EREMOTEIO; 131 132 if (error) 133 return error; 134 135 return answer; 136} 137 138static void vprbrd_gpioa_set(struct gpio_chip *chip, 139 unsigned offset, int value) 140{ 141 int ret; 142 struct vprbrd_gpio *gpio = 143 container_of(chip, struct vprbrd_gpio, gpioa); 144 struct vprbrd *vb = gpio->vb; 145 struct vprbrd_gpioa_msg *gamsg = (struct vprbrd_gpioa_msg *)vb->buf; 146 147 if (gpio->gpioa_out & (1 << offset)) { 148 if (value) 149 gpio->gpioa_val |= (1 << offset); 150 else 151 gpio->gpioa_val &= ~(1 << offset); 152 153 mutex_lock(&vb->lock); 154 155 gamsg->cmd = VPRBRD_GPIOA_CMD_SETOUT; 156 gamsg->clk = 0x00; 157 gamsg->offset = offset; 158 gamsg->t1 = 0x00; 159 gamsg->t2 = 0x00; 160 gamsg->invert = 0x00; 161 gamsg->pwmlevel = 0x00; 162 gamsg->outval = value; 163 gamsg->risefall = 0x00; 164 gamsg->answer = 0x00; 165 gamsg->__fill = 0x00; 166 167 ret = usb_control_msg(vb->usb_dev, 168 usb_sndctrlpipe(vb->usb_dev, 0), 169 VPRBRD_USB_REQUEST_GPIOA, VPRBRD_USB_TYPE_OUT, 170 0x0000, 0x0000, gamsg, 171 sizeof(struct vprbrd_gpioa_msg), VPRBRD_USB_TIMEOUT_MS); 172 173 mutex_unlock(&vb->lock); 174 175 if (ret != sizeof(struct vprbrd_gpioa_msg)) 176 dev_err(chip->dev, "usb error setting pin value\n"); 177 } 178} 179 180static int vprbrd_gpioa_direction_input(struct gpio_chip *chip, 181 unsigned offset) 182{ 183 int ret; 184 struct vprbrd_gpio *gpio = 185 container_of(chip, struct vprbrd_gpio, gpioa); 186 struct vprbrd *vb = gpio->vb; 187 struct vprbrd_gpioa_msg *gamsg = (struct vprbrd_gpioa_msg *)vb->buf; 188 189 gpio->gpioa_out &= ~(1 << offset); 190 191 mutex_lock(&vb->lock); 192 193 gamsg->cmd = VPRBRD_GPIOA_CMD_SETIN; 194 gamsg->clk = gpioa_clk; 195 gamsg->offset = offset; 196 gamsg->t1 = 0x00; 197 gamsg->t2 = 0x00; 198 gamsg->invert = 0x00; 199 gamsg->pwmlevel = 0x00; 200 gamsg->outval = 0x00; 201 gamsg->risefall = 0x00; 202 gamsg->answer = 0x00; 203 gamsg->__fill = 0x00; 204 205 ret = usb_control_msg(vb->usb_dev, usb_sndctrlpipe(vb->usb_dev, 0), 206 VPRBRD_USB_REQUEST_GPIOA, VPRBRD_USB_TYPE_OUT, 0x0000, 207 0x0000, gamsg, sizeof(struct vprbrd_gpioa_msg), 208 VPRBRD_USB_TIMEOUT_MS); 209 210 mutex_unlock(&vb->lock); 211 212 if (ret != sizeof(struct vprbrd_gpioa_msg)) 213 return -EREMOTEIO; 214 215 return 0; 216} 217 218static int vprbrd_gpioa_direction_output(struct gpio_chip *chip, 219 unsigned offset, int value) 220{ 221 int ret; 222 struct vprbrd_gpio *gpio = 223 container_of(chip, struct vprbrd_gpio, gpioa); 224 struct vprbrd *vb = gpio->vb; 225 struct vprbrd_gpioa_msg *gamsg = (struct vprbrd_gpioa_msg *)vb->buf; 226 227 gpio->gpioa_out |= (1 << offset); 228 if (value) 229 gpio->gpioa_val |= (1 << offset); 230 else 231 gpio->gpioa_val &= ~(1 << offset); 232 233 mutex_lock(&vb->lock); 234 235 gamsg->cmd = VPRBRD_GPIOA_CMD_SETOUT; 236 gamsg->clk = 0x00; 237 gamsg->offset = offset; 238 gamsg->t1 = 0x00; 239 gamsg->t2 = 0x00; 240 gamsg->invert = 0x00; 241 gamsg->pwmlevel = 0x00; 242 gamsg->outval = value; 243 gamsg->risefall = 0x00; 244 gamsg->answer = 0x00; 245 gamsg->__fill = 0x00; 246 247 ret = usb_control_msg(vb->usb_dev, usb_sndctrlpipe(vb->usb_dev, 0), 248 VPRBRD_USB_REQUEST_GPIOA, VPRBRD_USB_TYPE_OUT, 0x0000, 249 0x0000, gamsg, sizeof(struct vprbrd_gpioa_msg), 250 VPRBRD_USB_TIMEOUT_MS); 251 252 mutex_unlock(&vb->lock); 253 254 if (ret != sizeof(struct vprbrd_gpioa_msg)) 255 return -EREMOTEIO; 256 257 return 0; 258} 259 260/* ----- end of gpio a chip ---------------------------------------------- */ 261 262/* ----- begin of gipo b chip -------------------------------------------- */ 263 264static int vprbrd_gpiob_setdir(struct vprbrd *vb, unsigned offset, 265 unsigned dir) 266{ 267 struct vprbrd_gpiob_msg *gbmsg = (struct vprbrd_gpiob_msg *)vb->buf; 268 int ret; 269 270 gbmsg->cmd = VPRBRD_GPIOB_CMD_SETDIR; 271 gbmsg->val = cpu_to_be16(dir << offset); 272 gbmsg->mask = cpu_to_be16(0x0001 << offset); 273 274 ret = usb_control_msg(vb->usb_dev, usb_sndctrlpipe(vb->usb_dev, 0), 275 VPRBRD_USB_REQUEST_GPIOB, VPRBRD_USB_TYPE_OUT, 0x0000, 276 0x0000, gbmsg, sizeof(struct vprbrd_gpiob_msg), 277 VPRBRD_USB_TIMEOUT_MS); 278 279 if (ret != sizeof(struct vprbrd_gpiob_msg)) 280 return -EREMOTEIO; 281 282 return 0; 283} 284 285static int vprbrd_gpiob_get(struct gpio_chip *chip, 286 unsigned offset) 287{ 288 int ret; 289 u16 val; 290 struct vprbrd_gpio *gpio = 291 container_of(chip, struct vprbrd_gpio, gpiob); 292 struct vprbrd *vb = gpio->vb; 293 struct vprbrd_gpiob_msg *gbmsg = (struct vprbrd_gpiob_msg *)vb->buf; 294 295 /* if io is set to output, just return the saved value */ 296 if (gpio->gpiob_out & (1 << offset)) 297 return gpio->gpiob_val & (1 << offset); 298 299 mutex_lock(&vb->lock); 300 301 ret = usb_control_msg(vb->usb_dev, usb_rcvctrlpipe(vb->usb_dev, 0), 302 VPRBRD_USB_REQUEST_GPIOB, VPRBRD_USB_TYPE_IN, 0x0000, 303 0x0000, gbmsg, sizeof(struct vprbrd_gpiob_msg), 304 VPRBRD_USB_TIMEOUT_MS); 305 val = gbmsg->val; 306 307 mutex_unlock(&vb->lock); 308 309 if (ret != sizeof(struct vprbrd_gpiob_msg)) 310 return ret; 311 312 /* cache the read values */ 313 gpio->gpiob_val = be16_to_cpu(val); 314 315 return (gpio->gpiob_val >> offset) & 0x1; 316} 317 318static void vprbrd_gpiob_set(struct gpio_chip *chip, 319 unsigned offset, int value) 320{ 321 int ret; 322 struct vprbrd_gpio *gpio = 323 container_of(chip, struct vprbrd_gpio, gpiob); 324 struct vprbrd *vb = gpio->vb; 325 struct vprbrd_gpiob_msg *gbmsg = (struct vprbrd_gpiob_msg *)vb->buf; 326 327 if (gpio->gpiob_out & (1 << offset)) { 328 if (value) 329 gpio->gpiob_val |= (1 << offset); 330 else 331 gpio->gpiob_val &= ~(1 << offset); 332 333 mutex_lock(&vb->lock); 334 335 gbmsg->cmd = VPRBRD_GPIOB_CMD_SETVAL; 336 gbmsg->val = cpu_to_be16(value << offset); 337 gbmsg->mask = cpu_to_be16(0x0001 << offset); 338 339 ret = usb_control_msg(vb->usb_dev, 340 usb_sndctrlpipe(vb->usb_dev, 0), 341 VPRBRD_USB_REQUEST_GPIOB, VPRBRD_USB_TYPE_OUT, 342 0x0000, 0x0000, gbmsg, 343 sizeof(struct vprbrd_gpiob_msg), VPRBRD_USB_TIMEOUT_MS); 344 345 mutex_unlock(&vb->lock); 346 347 if (ret != sizeof(struct vprbrd_gpiob_msg)) 348 dev_err(chip->dev, "usb error setting pin value\n"); 349 } 350} 351 352static int vprbrd_gpiob_direction_input(struct gpio_chip *chip, 353 unsigned offset) 354{ 355 int ret; 356 struct vprbrd_gpio *gpio = 357 container_of(chip, struct vprbrd_gpio, gpiob); 358 struct vprbrd *vb = gpio->vb; 359 360 gpio->gpiob_out &= ~(1 << offset); 361 362 mutex_lock(&vb->lock); 363 364 ret = vprbrd_gpiob_setdir(vb, offset, 0); 365 366 mutex_unlock(&vb->lock); 367 368 if (ret) 369 dev_err(chip->dev, "usb error setting pin to input\n"); 370 371 return ret; 372} 373 374static int vprbrd_gpiob_direction_output(struct gpio_chip *chip, 375 unsigned offset, int value) 376{ 377 int ret; 378 struct vprbrd_gpio *gpio = 379 container_of(chip, struct vprbrd_gpio, gpiob); 380 struct vprbrd *vb = gpio->vb; 381 382 gpio->gpiob_out |= (1 << offset); 383 384 mutex_lock(&vb->lock); 385 386 ret = vprbrd_gpiob_setdir(vb, offset, 1); 387 if (ret) 388 dev_err(chip->dev, "usb error setting pin to output\n"); 389 390 mutex_unlock(&vb->lock); 391 392 vprbrd_gpiob_set(chip, offset, value); 393 394 return ret; 395} 396 397/* ----- end of gpio b chip ---------------------------------------------- */ 398 399static int vprbrd_gpio_probe(struct platform_device *pdev) 400{ 401 struct vprbrd *vb = dev_get_drvdata(pdev->dev.parent); 402 struct vprbrd_gpio *vb_gpio; 403 int ret; 404 405 vb_gpio = devm_kzalloc(&pdev->dev, sizeof(*vb_gpio), GFP_KERNEL); 406 if (vb_gpio == NULL) 407 return -ENOMEM; 408 409 vb_gpio->vb = vb; 410 /* registering gpio a */ 411 vb_gpio->gpioa.label = "viperboard gpio a"; 412 vb_gpio->gpioa.dev = &pdev->dev; 413 vb_gpio->gpioa.owner = THIS_MODULE; 414 vb_gpio->gpioa.base = -1; 415 vb_gpio->gpioa.ngpio = 16; 416 vb_gpio->gpioa.can_sleep = true; 417 vb_gpio->gpioa.set = vprbrd_gpioa_set; 418 vb_gpio->gpioa.get = vprbrd_gpioa_get; 419 vb_gpio->gpioa.direction_input = vprbrd_gpioa_direction_input; 420 vb_gpio->gpioa.direction_output = vprbrd_gpioa_direction_output; 421 ret = gpiochip_add(&vb_gpio->gpioa); 422 if (ret < 0) { 423 dev_err(vb_gpio->gpioa.dev, "could not add gpio a"); 424 goto err_gpioa; 425 } 426 427 /* registering gpio b */ 428 vb_gpio->gpiob.label = "viperboard gpio b"; 429 vb_gpio->gpiob.dev = &pdev->dev; 430 vb_gpio->gpiob.owner = THIS_MODULE; 431 vb_gpio->gpiob.base = -1; 432 vb_gpio->gpiob.ngpio = 16; 433 vb_gpio->gpiob.can_sleep = true; 434 vb_gpio->gpiob.set = vprbrd_gpiob_set; 435 vb_gpio->gpiob.get = vprbrd_gpiob_get; 436 vb_gpio->gpiob.direction_input = vprbrd_gpiob_direction_input; 437 vb_gpio->gpiob.direction_output = vprbrd_gpiob_direction_output; 438 ret = gpiochip_add(&vb_gpio->gpiob); 439 if (ret < 0) { 440 dev_err(vb_gpio->gpiob.dev, "could not add gpio b"); 441 goto err_gpiob; 442 } 443 444 platform_set_drvdata(pdev, vb_gpio); 445 446 return ret; 447 448err_gpiob: 449 gpiochip_remove(&vb_gpio->gpioa); 450 451err_gpioa: 452 return ret; 453} 454 455static int vprbrd_gpio_remove(struct platform_device *pdev) 456{ 457 struct vprbrd_gpio *vb_gpio = platform_get_drvdata(pdev); 458 459 gpiochip_remove(&vb_gpio->gpiob); 460 461 return 0; 462} 463 464static struct platform_driver vprbrd_gpio_driver = { 465 .driver.name = "viperboard-gpio", 466 .driver.owner = THIS_MODULE, 467 .probe = vprbrd_gpio_probe, 468 .remove = vprbrd_gpio_remove, 469}; 470 471static int __init vprbrd_gpio_init(void) 472{ 473 switch (gpioa_freq) { 474 case 1000000: 475 gpioa_clk = VPRBRD_GPIOA_CLK_1MHZ; 476 break; 477 case 100000: 478 gpioa_clk = VPRBRD_GPIOA_CLK_100KHZ; 479 break; 480 case 10000: 481 gpioa_clk = VPRBRD_GPIOA_CLK_10KHZ; 482 break; 483 case 1000: 484 gpioa_clk = VPRBRD_GPIOA_CLK_1KHZ; 485 break; 486 case 100: 487 gpioa_clk = VPRBRD_GPIOA_CLK_100HZ; 488 break; 489 case 10: 490 gpioa_clk = VPRBRD_GPIOA_CLK_10HZ; 491 break; 492 default: 493 pr_warn("invalid gpioa_freq (%d)\n", gpioa_freq); 494 gpioa_clk = VPRBRD_GPIOA_CLK_1KHZ; 495 } 496 497 return platform_driver_register(&vprbrd_gpio_driver); 498} 499subsys_initcall(vprbrd_gpio_init); 500 501static void __exit vprbrd_gpio_exit(void) 502{ 503 platform_driver_unregister(&vprbrd_gpio_driver); 504} 505module_exit(vprbrd_gpio_exit); 506 507MODULE_AUTHOR("Lars Poeschel <poeschel@lemonage.de>"); 508MODULE_DESCRIPTION("GPIO driver for Nano River Techs Viperboard"); 509MODULE_LICENSE("GPL"); 510MODULE_ALIAS("platform:viperboard-gpio"); 511