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