root/drivers/gpio/gpio-viperboard.c

/* [<][>][^][v][top][bottom][index][help] */

DEFINITIONS

This source file includes following definitions.
  1. vprbrd_gpioa_get
  2. vprbrd_gpioa_set
  3. vprbrd_gpioa_direction_input
  4. vprbrd_gpioa_direction_output
  5. vprbrd_gpiob_setdir
  6. vprbrd_gpiob_get
  7. vprbrd_gpiob_set
  8. vprbrd_gpiob_direction_input
  9. vprbrd_gpiob_direction_output
  10. vprbrd_gpio_probe
  11. vprbrd_gpio_init
  12. vprbrd_gpio_exit

   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 void vprbrd_gpioa_set(struct gpio_chip *chip,
 132                 unsigned int offset, int value)
 133 {
 134         int ret;
 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                 if (value)
 141                         gpio->gpioa_val |= (1 << offset);
 142                 else
 143                         gpio->gpioa_val &= ~(1 << offset);
 144 
 145                 mutex_lock(&vb->lock);
 146 
 147                 gamsg->cmd = VPRBRD_GPIOA_CMD_SETOUT;
 148                 gamsg->clk = 0x00;
 149                 gamsg->offset = offset;
 150                 gamsg->t1 = 0x00;
 151                 gamsg->t2 = 0x00;
 152                 gamsg->invert = 0x00;
 153                 gamsg->pwmlevel = 0x00;
 154                 gamsg->outval = value;
 155                 gamsg->risefall = 0x00;
 156                 gamsg->answer = 0x00;
 157                 gamsg->__fill = 0x00;
 158 
 159                 ret = usb_control_msg(vb->usb_dev,
 160                         usb_sndctrlpipe(vb->usb_dev, 0),
 161                         VPRBRD_USB_REQUEST_GPIOA, VPRBRD_USB_TYPE_OUT,
 162                         0x0000, 0x0000, gamsg,
 163                         sizeof(struct vprbrd_gpioa_msg), VPRBRD_USB_TIMEOUT_MS);
 164 
 165                 mutex_unlock(&vb->lock);
 166 
 167                 if (ret != sizeof(struct vprbrd_gpioa_msg))
 168                         dev_err(chip->parent, "usb error setting pin value\n");
 169         }
 170 }
 171 
 172 static int vprbrd_gpioa_direction_input(struct gpio_chip *chip,
 173                         unsigned int offset)
 174 {
 175         int ret;
 176         struct vprbrd_gpio *gpio = gpiochip_get_data(chip);
 177         struct vprbrd *vb = gpio->vb;
 178         struct vprbrd_gpioa_msg *gamsg = (struct vprbrd_gpioa_msg *)vb->buf;
 179 
 180         gpio->gpioa_out &= ~(1 << offset);
 181 
 182         mutex_lock(&vb->lock);
 183 
 184         gamsg->cmd = VPRBRD_GPIOA_CMD_SETIN;
 185         gamsg->clk = gpioa_clk;
 186         gamsg->offset = offset;
 187         gamsg->t1 = 0x00;
 188         gamsg->t2 = 0x00;
 189         gamsg->invert = 0x00;
 190         gamsg->pwmlevel = 0x00;
 191         gamsg->outval = 0x00;
 192         gamsg->risefall = 0x00;
 193         gamsg->answer = 0x00;
 194         gamsg->__fill = 0x00;
 195 
 196         ret = usb_control_msg(vb->usb_dev, usb_sndctrlpipe(vb->usb_dev, 0),
 197                 VPRBRD_USB_REQUEST_GPIOA, VPRBRD_USB_TYPE_OUT, 0x0000,
 198                 0x0000, gamsg, sizeof(struct vprbrd_gpioa_msg),
 199                 VPRBRD_USB_TIMEOUT_MS);
 200 
 201         mutex_unlock(&vb->lock);
 202 
 203         if (ret != sizeof(struct vprbrd_gpioa_msg))
 204                 return -EREMOTEIO;
 205 
 206         return 0;
 207 }
 208 
 209 static int vprbrd_gpioa_direction_output(struct gpio_chip *chip,
 210                         unsigned int offset, int value)
 211 {
 212         int ret;
 213         struct vprbrd_gpio *gpio = gpiochip_get_data(chip);
 214         struct vprbrd *vb = gpio->vb;
 215         struct vprbrd_gpioa_msg *gamsg = (struct vprbrd_gpioa_msg *)vb->buf;
 216 
 217         gpio->gpioa_out |= (1 << offset);
 218         if (value)
 219                 gpio->gpioa_val |= (1 << offset);
 220         else
 221                 gpio->gpioa_val &= ~(1 << offset);
 222 
 223         mutex_lock(&vb->lock);
 224 
 225         gamsg->cmd = VPRBRD_GPIOA_CMD_SETOUT;
 226         gamsg->clk = 0x00;
 227         gamsg->offset = offset;
 228         gamsg->t1 = 0x00;
 229         gamsg->t2 = 0x00;
 230         gamsg->invert = 0x00;
 231         gamsg->pwmlevel = 0x00;
 232         gamsg->outval = value;
 233         gamsg->risefall = 0x00;
 234         gamsg->answer = 0x00;
 235         gamsg->__fill = 0x00;
 236 
 237         ret = usb_control_msg(vb->usb_dev, usb_sndctrlpipe(vb->usb_dev, 0),
 238                 VPRBRD_USB_REQUEST_GPIOA, VPRBRD_USB_TYPE_OUT, 0x0000,
 239                 0x0000, gamsg, sizeof(struct vprbrd_gpioa_msg),
 240                 VPRBRD_USB_TIMEOUT_MS);
 241 
 242         mutex_unlock(&vb->lock);
 243 
 244         if (ret != sizeof(struct vprbrd_gpioa_msg))
 245                 return -EREMOTEIO;
 246 
 247         return 0;
 248 }
 249 
 250 /* ----- end of gpio a chip ---------------------------------------------- */
 251 
 252 /* ----- begin of gipo b chip -------------------------------------------- */
 253 
 254 static int vprbrd_gpiob_setdir(struct vprbrd *vb, unsigned int offset,
 255         unsigned int dir)
 256 {
 257         struct vprbrd_gpiob_msg *gbmsg = (struct vprbrd_gpiob_msg *)vb->buf;
 258         int ret;
 259 
 260         gbmsg->cmd = VPRBRD_GPIOB_CMD_SETDIR;
 261         gbmsg->val = cpu_to_be16(dir << offset);
 262         gbmsg->mask = cpu_to_be16(0x0001 << offset);
 263 
 264         ret = usb_control_msg(vb->usb_dev, usb_sndctrlpipe(vb->usb_dev, 0),
 265                 VPRBRD_USB_REQUEST_GPIOB, VPRBRD_USB_TYPE_OUT, 0x0000,
 266                 0x0000, gbmsg, sizeof(struct vprbrd_gpiob_msg),
 267                 VPRBRD_USB_TIMEOUT_MS);
 268 
 269         if (ret != sizeof(struct vprbrd_gpiob_msg))
 270                 return -EREMOTEIO;
 271 
 272         return 0;
 273 }
 274 
 275 static int vprbrd_gpiob_get(struct gpio_chip *chip,
 276                 unsigned int offset)
 277 {
 278         int ret;
 279         u16 val;
 280         struct vprbrd_gpio *gpio = gpiochip_get_data(chip);
 281         struct vprbrd *vb = gpio->vb;
 282         struct vprbrd_gpiob_msg *gbmsg = (struct vprbrd_gpiob_msg *)vb->buf;
 283 
 284         /* if io is set to output, just return the saved value */
 285         if (gpio->gpiob_out & (1 << offset))
 286                 return gpio->gpiob_val & (1 << offset);
 287 
 288         mutex_lock(&vb->lock);
 289 
 290         ret = usb_control_msg(vb->usb_dev, usb_rcvctrlpipe(vb->usb_dev, 0),
 291                 VPRBRD_USB_REQUEST_GPIOB, VPRBRD_USB_TYPE_IN, 0x0000,
 292                 0x0000, gbmsg,  sizeof(struct vprbrd_gpiob_msg),
 293                 VPRBRD_USB_TIMEOUT_MS);
 294         val = gbmsg->val;
 295 
 296         mutex_unlock(&vb->lock);
 297 
 298         if (ret != sizeof(struct vprbrd_gpiob_msg))
 299                 return ret;
 300 
 301         /* cache the read values */
 302         gpio->gpiob_val = be16_to_cpu(val);
 303 
 304         return (gpio->gpiob_val >> offset) & 0x1;
 305 }
 306 
 307 static void vprbrd_gpiob_set(struct gpio_chip *chip,
 308                 unsigned int offset, int value)
 309 {
 310         int ret;
 311         struct vprbrd_gpio *gpio = gpiochip_get_data(chip);
 312         struct vprbrd *vb = gpio->vb;
 313         struct vprbrd_gpiob_msg *gbmsg = (struct vprbrd_gpiob_msg *)vb->buf;
 314 
 315         if (gpio->gpiob_out & (1 << offset)) {
 316                 if (value)
 317                         gpio->gpiob_val |= (1 << offset);
 318                 else
 319                         gpio->gpiob_val &= ~(1 << offset);
 320 
 321                 mutex_lock(&vb->lock);
 322 
 323                 gbmsg->cmd = VPRBRD_GPIOB_CMD_SETVAL;
 324                 gbmsg->val = cpu_to_be16(value << offset);
 325                 gbmsg->mask = cpu_to_be16(0x0001 << offset);
 326 
 327                 ret = usb_control_msg(vb->usb_dev,
 328                         usb_sndctrlpipe(vb->usb_dev, 0),
 329                         VPRBRD_USB_REQUEST_GPIOB, VPRBRD_USB_TYPE_OUT,
 330                         0x0000, 0x0000, gbmsg,
 331                         sizeof(struct vprbrd_gpiob_msg), VPRBRD_USB_TIMEOUT_MS);
 332 
 333                 mutex_unlock(&vb->lock);
 334 
 335                 if (ret != sizeof(struct vprbrd_gpiob_msg))
 336                         dev_err(chip->parent, "usb error setting pin value\n");
 337         }
 338 }
 339 
 340 static int vprbrd_gpiob_direction_input(struct gpio_chip *chip,
 341                         unsigned int offset)
 342 {
 343         int ret;
 344         struct vprbrd_gpio *gpio = gpiochip_get_data(chip);
 345         struct vprbrd *vb = gpio->vb;
 346 
 347         gpio->gpiob_out &= ~(1 << offset);
 348 
 349         mutex_lock(&vb->lock);
 350 
 351         ret = vprbrd_gpiob_setdir(vb, offset, 0);
 352 
 353         mutex_unlock(&vb->lock);
 354 
 355         if (ret)
 356                 dev_err(chip->parent, "usb error setting pin to input\n");
 357 
 358         return ret;
 359 }
 360 
 361 static int vprbrd_gpiob_direction_output(struct gpio_chip *chip,
 362                         unsigned int offset, int value)
 363 {
 364         int ret;
 365         struct vprbrd_gpio *gpio = gpiochip_get_data(chip);
 366         struct vprbrd *vb = gpio->vb;
 367 
 368         gpio->gpiob_out |= (1 << offset);
 369 
 370         mutex_lock(&vb->lock);
 371 
 372         ret = vprbrd_gpiob_setdir(vb, offset, 1);
 373         if (ret)
 374                 dev_err(chip->parent, "usb error setting pin to output\n");
 375 
 376         mutex_unlock(&vb->lock);
 377 
 378         vprbrd_gpiob_set(chip, offset, value);
 379 
 380         return ret;
 381 }
 382 
 383 /* ----- end of gpio b chip ---------------------------------------------- */
 384 
 385 static int vprbrd_gpio_probe(struct platform_device *pdev)
 386 {
 387         struct vprbrd *vb = dev_get_drvdata(pdev->dev.parent);
 388         struct vprbrd_gpio *vb_gpio;
 389         int ret;
 390 
 391         vb_gpio = devm_kzalloc(&pdev->dev, sizeof(*vb_gpio), GFP_KERNEL);
 392         if (vb_gpio == NULL)
 393                 return -ENOMEM;
 394 
 395         vb_gpio->vb = vb;
 396         /* registering gpio a */
 397         vb_gpio->gpioa.label = "viperboard gpio a";
 398         vb_gpio->gpioa.parent = &pdev->dev;
 399         vb_gpio->gpioa.owner = THIS_MODULE;
 400         vb_gpio->gpioa.base = -1;
 401         vb_gpio->gpioa.ngpio = 16;
 402         vb_gpio->gpioa.can_sleep = true;
 403         vb_gpio->gpioa.set = vprbrd_gpioa_set;
 404         vb_gpio->gpioa.get = vprbrd_gpioa_get;
 405         vb_gpio->gpioa.direction_input = vprbrd_gpioa_direction_input;
 406         vb_gpio->gpioa.direction_output = vprbrd_gpioa_direction_output;
 407         ret = devm_gpiochip_add_data(&pdev->dev, &vb_gpio->gpioa, vb_gpio);
 408         if (ret < 0) {
 409                 dev_err(vb_gpio->gpioa.parent, "could not add gpio a");
 410                 return ret;
 411         }
 412 
 413         /* registering gpio b */
 414         vb_gpio->gpiob.label = "viperboard gpio b";
 415         vb_gpio->gpiob.parent = &pdev->dev;
 416         vb_gpio->gpiob.owner = THIS_MODULE;
 417         vb_gpio->gpiob.base = -1;
 418         vb_gpio->gpiob.ngpio = 16;
 419         vb_gpio->gpiob.can_sleep = true;
 420         vb_gpio->gpiob.set = vprbrd_gpiob_set;
 421         vb_gpio->gpiob.get = vprbrd_gpiob_get;
 422         vb_gpio->gpiob.direction_input = vprbrd_gpiob_direction_input;
 423         vb_gpio->gpiob.direction_output = vprbrd_gpiob_direction_output;
 424         ret = devm_gpiochip_add_data(&pdev->dev, &vb_gpio->gpiob, vb_gpio);
 425         if (ret < 0) {
 426                 dev_err(vb_gpio->gpiob.parent, "could not add gpio b");
 427                 return ret;
 428         }
 429 
 430         platform_set_drvdata(pdev, vb_gpio);
 431 
 432         return ret;
 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");

/* [<][>][^][v][top][bottom][index][help] */