0001
0002
0003
0004
0005
0006
0007
0008
0009
0010 #include <linux/kernel.h>
0011 #include <linux/errno.h>
0012 #include <linux/module.h>
0013 #include <linux/slab.h>
0014 #include <linux/types.h>
0015 #include <linux/mutex.h>
0016 #include <linux/platform_device.h>
0017 #include <linux/usb.h>
0018 #include <linux/gpio/driver.h>
0019
0020 #include <linux/mfd/viperboard.h>
0021
0022 #define VPRBRD_GPIOA_CLK_1MHZ 0
0023 #define VPRBRD_GPIOA_CLK_100KHZ 1
0024 #define VPRBRD_GPIOA_CLK_10KHZ 2
0025 #define VPRBRD_GPIOA_CLK_1KHZ 3
0026 #define VPRBRD_GPIOA_CLK_100HZ 4
0027 #define VPRBRD_GPIOA_CLK_10HZ 5
0028
0029 #define VPRBRD_GPIOA_FREQ_DEFAULT 1000
0030
0031 #define VPRBRD_GPIOA_CMD_CONT 0x00
0032 #define VPRBRD_GPIOA_CMD_PULSE 0x01
0033 #define VPRBRD_GPIOA_CMD_PWM 0x02
0034 #define VPRBRD_GPIOA_CMD_SETOUT 0x03
0035 #define VPRBRD_GPIOA_CMD_SETIN 0x04
0036 #define VPRBRD_GPIOA_CMD_SETINT 0x05
0037 #define VPRBRD_GPIOA_CMD_GETIN 0x06
0038
0039 #define VPRBRD_GPIOB_CMD_SETDIR 0x00
0040 #define VPRBRD_GPIOB_CMD_SETVAL 0x01
0041
0042 struct vprbrd_gpioa_msg {
0043 u8 cmd;
0044 u8 clk;
0045 u8 offset;
0046 u8 t1;
0047 u8 t2;
0048 u8 invert;
0049 u8 pwmlevel;
0050 u8 outval;
0051 u8 risefall;
0052 u8 answer;
0053 u8 __fill;
0054 } __packed;
0055
0056 struct vprbrd_gpiob_msg {
0057 u8 cmd;
0058 u16 val;
0059 u16 mask;
0060 } __packed;
0061
0062 struct vprbrd_gpio {
0063 struct gpio_chip gpioa;
0064 u32 gpioa_out;
0065 u32 gpioa_val;
0066 struct gpio_chip gpiob;
0067 u32 gpiob_out;
0068 u32 gpiob_val;
0069 struct vprbrd *vb;
0070 };
0071
0072
0073 static unsigned char gpioa_clk;
0074 static unsigned int gpioa_freq = VPRBRD_GPIOA_FREQ_DEFAULT;
0075 module_param(gpioa_freq, uint, 0);
0076 MODULE_PARM_DESC(gpioa_freq,
0077 "gpio-a sampling freq in Hz (default is 1000Hz) valid values: 10, 100, 1000, 10000, 100000, 1000000");
0078
0079
0080
0081 static int vprbrd_gpioa_get(struct gpio_chip *chip,
0082 unsigned int offset)
0083 {
0084 int ret, answer, error = 0;
0085 struct vprbrd_gpio *gpio = gpiochip_get_data(chip);
0086 struct vprbrd *vb = gpio->vb;
0087 struct vprbrd_gpioa_msg *gamsg = (struct vprbrd_gpioa_msg *)vb->buf;
0088
0089
0090 if (gpio->gpioa_out & (1 << offset))
0091 return !!(gpio->gpioa_val & (1 << offset));
0092
0093 mutex_lock(&vb->lock);
0094
0095 gamsg->cmd = VPRBRD_GPIOA_CMD_GETIN;
0096 gamsg->clk = 0x00;
0097 gamsg->offset = offset;
0098 gamsg->t1 = 0x00;
0099 gamsg->t2 = 0x00;
0100 gamsg->invert = 0x00;
0101 gamsg->pwmlevel = 0x00;
0102 gamsg->outval = 0x00;
0103 gamsg->risefall = 0x00;
0104 gamsg->answer = 0x00;
0105 gamsg->__fill = 0x00;
0106
0107 ret = usb_control_msg(vb->usb_dev, usb_sndctrlpipe(vb->usb_dev, 0),
0108 VPRBRD_USB_REQUEST_GPIOA, VPRBRD_USB_TYPE_OUT, 0x0000,
0109 0x0000, gamsg, sizeof(struct vprbrd_gpioa_msg),
0110 VPRBRD_USB_TIMEOUT_MS);
0111 if (ret != sizeof(struct vprbrd_gpioa_msg))
0112 error = -EREMOTEIO;
0113
0114 ret = usb_control_msg(vb->usb_dev, usb_rcvctrlpipe(vb->usb_dev, 0),
0115 VPRBRD_USB_REQUEST_GPIOA, VPRBRD_USB_TYPE_IN, 0x0000,
0116 0x0000, gamsg, sizeof(struct vprbrd_gpioa_msg),
0117 VPRBRD_USB_TIMEOUT_MS);
0118 answer = gamsg->answer & 0x01;
0119
0120 mutex_unlock(&vb->lock);
0121
0122 if (ret != sizeof(struct vprbrd_gpioa_msg))
0123 error = -EREMOTEIO;
0124
0125 if (error)
0126 return error;
0127
0128 return answer;
0129 }
0130
0131 static void vprbrd_gpioa_set(struct gpio_chip *chip,
0132 unsigned int offset, int value)
0133 {
0134 int ret;
0135 struct vprbrd_gpio *gpio = gpiochip_get_data(chip);
0136 struct vprbrd *vb = gpio->vb;
0137 struct vprbrd_gpioa_msg *gamsg = (struct vprbrd_gpioa_msg *)vb->buf;
0138
0139 if (gpio->gpioa_out & (1 << offset)) {
0140 if (value)
0141 gpio->gpioa_val |= (1 << offset);
0142 else
0143 gpio->gpioa_val &= ~(1 << offset);
0144
0145 mutex_lock(&vb->lock);
0146
0147 gamsg->cmd = VPRBRD_GPIOA_CMD_SETOUT;
0148 gamsg->clk = 0x00;
0149 gamsg->offset = offset;
0150 gamsg->t1 = 0x00;
0151 gamsg->t2 = 0x00;
0152 gamsg->invert = 0x00;
0153 gamsg->pwmlevel = 0x00;
0154 gamsg->outval = value;
0155 gamsg->risefall = 0x00;
0156 gamsg->answer = 0x00;
0157 gamsg->__fill = 0x00;
0158
0159 ret = usb_control_msg(vb->usb_dev,
0160 usb_sndctrlpipe(vb->usb_dev, 0),
0161 VPRBRD_USB_REQUEST_GPIOA, VPRBRD_USB_TYPE_OUT,
0162 0x0000, 0x0000, gamsg,
0163 sizeof(struct vprbrd_gpioa_msg), VPRBRD_USB_TIMEOUT_MS);
0164
0165 mutex_unlock(&vb->lock);
0166
0167 if (ret != sizeof(struct vprbrd_gpioa_msg))
0168 dev_err(chip->parent, "usb error setting pin value\n");
0169 }
0170 }
0171
0172 static int vprbrd_gpioa_direction_input(struct gpio_chip *chip,
0173 unsigned int offset)
0174 {
0175 int ret;
0176 struct vprbrd_gpio *gpio = gpiochip_get_data(chip);
0177 struct vprbrd *vb = gpio->vb;
0178 struct vprbrd_gpioa_msg *gamsg = (struct vprbrd_gpioa_msg *)vb->buf;
0179
0180 gpio->gpioa_out &= ~(1 << offset);
0181
0182 mutex_lock(&vb->lock);
0183
0184 gamsg->cmd = VPRBRD_GPIOA_CMD_SETIN;
0185 gamsg->clk = gpioa_clk;
0186 gamsg->offset = offset;
0187 gamsg->t1 = 0x00;
0188 gamsg->t2 = 0x00;
0189 gamsg->invert = 0x00;
0190 gamsg->pwmlevel = 0x00;
0191 gamsg->outval = 0x00;
0192 gamsg->risefall = 0x00;
0193 gamsg->answer = 0x00;
0194 gamsg->__fill = 0x00;
0195
0196 ret = usb_control_msg(vb->usb_dev, usb_sndctrlpipe(vb->usb_dev, 0),
0197 VPRBRD_USB_REQUEST_GPIOA, VPRBRD_USB_TYPE_OUT, 0x0000,
0198 0x0000, gamsg, sizeof(struct vprbrd_gpioa_msg),
0199 VPRBRD_USB_TIMEOUT_MS);
0200
0201 mutex_unlock(&vb->lock);
0202
0203 if (ret != sizeof(struct vprbrd_gpioa_msg))
0204 return -EREMOTEIO;
0205
0206 return 0;
0207 }
0208
0209 static int vprbrd_gpioa_direction_output(struct gpio_chip *chip,
0210 unsigned int offset, int value)
0211 {
0212 int ret;
0213 struct vprbrd_gpio *gpio = gpiochip_get_data(chip);
0214 struct vprbrd *vb = gpio->vb;
0215 struct vprbrd_gpioa_msg *gamsg = (struct vprbrd_gpioa_msg *)vb->buf;
0216
0217 gpio->gpioa_out |= (1 << offset);
0218 if (value)
0219 gpio->gpioa_val |= (1 << offset);
0220 else
0221 gpio->gpioa_val &= ~(1 << offset);
0222
0223 mutex_lock(&vb->lock);
0224
0225 gamsg->cmd = VPRBRD_GPIOA_CMD_SETOUT;
0226 gamsg->clk = 0x00;
0227 gamsg->offset = offset;
0228 gamsg->t1 = 0x00;
0229 gamsg->t2 = 0x00;
0230 gamsg->invert = 0x00;
0231 gamsg->pwmlevel = 0x00;
0232 gamsg->outval = value;
0233 gamsg->risefall = 0x00;
0234 gamsg->answer = 0x00;
0235 gamsg->__fill = 0x00;
0236
0237 ret = usb_control_msg(vb->usb_dev, usb_sndctrlpipe(vb->usb_dev, 0),
0238 VPRBRD_USB_REQUEST_GPIOA, VPRBRD_USB_TYPE_OUT, 0x0000,
0239 0x0000, gamsg, sizeof(struct vprbrd_gpioa_msg),
0240 VPRBRD_USB_TIMEOUT_MS);
0241
0242 mutex_unlock(&vb->lock);
0243
0244 if (ret != sizeof(struct vprbrd_gpioa_msg))
0245 return -EREMOTEIO;
0246
0247 return 0;
0248 }
0249
0250
0251
0252
0253
0254 static int vprbrd_gpiob_setdir(struct vprbrd *vb, unsigned int offset,
0255 unsigned int dir)
0256 {
0257 struct vprbrd_gpiob_msg *gbmsg = (struct vprbrd_gpiob_msg *)vb->buf;
0258 int ret;
0259
0260 gbmsg->cmd = VPRBRD_GPIOB_CMD_SETDIR;
0261 gbmsg->val = cpu_to_be16(dir << offset);
0262 gbmsg->mask = cpu_to_be16(0x0001 << offset);
0263
0264 ret = usb_control_msg(vb->usb_dev, usb_sndctrlpipe(vb->usb_dev, 0),
0265 VPRBRD_USB_REQUEST_GPIOB, VPRBRD_USB_TYPE_OUT, 0x0000,
0266 0x0000, gbmsg, sizeof(struct vprbrd_gpiob_msg),
0267 VPRBRD_USB_TIMEOUT_MS);
0268
0269 if (ret != sizeof(struct vprbrd_gpiob_msg))
0270 return -EREMOTEIO;
0271
0272 return 0;
0273 }
0274
0275 static int vprbrd_gpiob_get(struct gpio_chip *chip,
0276 unsigned int offset)
0277 {
0278 int ret;
0279 u16 val;
0280 struct vprbrd_gpio *gpio = gpiochip_get_data(chip);
0281 struct vprbrd *vb = gpio->vb;
0282 struct vprbrd_gpiob_msg *gbmsg = (struct vprbrd_gpiob_msg *)vb->buf;
0283
0284
0285 if (gpio->gpiob_out & (1 << offset))
0286 return gpio->gpiob_val & (1 << offset);
0287
0288 mutex_lock(&vb->lock);
0289
0290 ret = usb_control_msg(vb->usb_dev, usb_rcvctrlpipe(vb->usb_dev, 0),
0291 VPRBRD_USB_REQUEST_GPIOB, VPRBRD_USB_TYPE_IN, 0x0000,
0292 0x0000, gbmsg, sizeof(struct vprbrd_gpiob_msg),
0293 VPRBRD_USB_TIMEOUT_MS);
0294 val = gbmsg->val;
0295
0296 mutex_unlock(&vb->lock);
0297
0298 if (ret != sizeof(struct vprbrd_gpiob_msg))
0299 return ret;
0300
0301
0302 gpio->gpiob_val = be16_to_cpu(val);
0303
0304 return (gpio->gpiob_val >> offset) & 0x1;
0305 }
0306
0307 static void vprbrd_gpiob_set(struct gpio_chip *chip,
0308 unsigned int offset, int value)
0309 {
0310 int ret;
0311 struct vprbrd_gpio *gpio = gpiochip_get_data(chip);
0312 struct vprbrd *vb = gpio->vb;
0313 struct vprbrd_gpiob_msg *gbmsg = (struct vprbrd_gpiob_msg *)vb->buf;
0314
0315 if (gpio->gpiob_out & (1 << offset)) {
0316 if (value)
0317 gpio->gpiob_val |= (1 << offset);
0318 else
0319 gpio->gpiob_val &= ~(1 << offset);
0320
0321 mutex_lock(&vb->lock);
0322
0323 gbmsg->cmd = VPRBRD_GPIOB_CMD_SETVAL;
0324 gbmsg->val = cpu_to_be16(value << offset);
0325 gbmsg->mask = cpu_to_be16(0x0001 << offset);
0326
0327 ret = usb_control_msg(vb->usb_dev,
0328 usb_sndctrlpipe(vb->usb_dev, 0),
0329 VPRBRD_USB_REQUEST_GPIOB, VPRBRD_USB_TYPE_OUT,
0330 0x0000, 0x0000, gbmsg,
0331 sizeof(struct vprbrd_gpiob_msg), VPRBRD_USB_TIMEOUT_MS);
0332
0333 mutex_unlock(&vb->lock);
0334
0335 if (ret != sizeof(struct vprbrd_gpiob_msg))
0336 dev_err(chip->parent, "usb error setting pin value\n");
0337 }
0338 }
0339
0340 static int vprbrd_gpiob_direction_input(struct gpio_chip *chip,
0341 unsigned int offset)
0342 {
0343 int ret;
0344 struct vprbrd_gpio *gpio = gpiochip_get_data(chip);
0345 struct vprbrd *vb = gpio->vb;
0346
0347 gpio->gpiob_out &= ~(1 << offset);
0348
0349 mutex_lock(&vb->lock);
0350
0351 ret = vprbrd_gpiob_setdir(vb, offset, 0);
0352
0353 mutex_unlock(&vb->lock);
0354
0355 if (ret)
0356 dev_err(chip->parent, "usb error setting pin to input\n");
0357
0358 return ret;
0359 }
0360
0361 static int vprbrd_gpiob_direction_output(struct gpio_chip *chip,
0362 unsigned int offset, int value)
0363 {
0364 int ret;
0365 struct vprbrd_gpio *gpio = gpiochip_get_data(chip);
0366 struct vprbrd *vb = gpio->vb;
0367
0368 gpio->gpiob_out |= (1 << offset);
0369
0370 mutex_lock(&vb->lock);
0371
0372 ret = vprbrd_gpiob_setdir(vb, offset, 1);
0373 if (ret)
0374 dev_err(chip->parent, "usb error setting pin to output\n");
0375
0376 mutex_unlock(&vb->lock);
0377
0378 vprbrd_gpiob_set(chip, offset, value);
0379
0380 return ret;
0381 }
0382
0383
0384
0385 static int vprbrd_gpio_probe(struct platform_device *pdev)
0386 {
0387 struct vprbrd *vb = dev_get_drvdata(pdev->dev.parent);
0388 struct vprbrd_gpio *vb_gpio;
0389 int ret;
0390
0391 vb_gpio = devm_kzalloc(&pdev->dev, sizeof(*vb_gpio), GFP_KERNEL);
0392 if (vb_gpio == NULL)
0393 return -ENOMEM;
0394
0395 vb_gpio->vb = vb;
0396
0397 vb_gpio->gpioa.label = "viperboard gpio a";
0398 vb_gpio->gpioa.parent = &pdev->dev;
0399 vb_gpio->gpioa.owner = THIS_MODULE;
0400 vb_gpio->gpioa.base = -1;
0401 vb_gpio->gpioa.ngpio = 16;
0402 vb_gpio->gpioa.can_sleep = true;
0403 vb_gpio->gpioa.set = vprbrd_gpioa_set;
0404 vb_gpio->gpioa.get = vprbrd_gpioa_get;
0405 vb_gpio->gpioa.direction_input = vprbrd_gpioa_direction_input;
0406 vb_gpio->gpioa.direction_output = vprbrd_gpioa_direction_output;
0407
0408 ret = devm_gpiochip_add_data(&pdev->dev, &vb_gpio->gpioa, vb_gpio);
0409 if (ret < 0)
0410 return ret;
0411
0412
0413 vb_gpio->gpiob.label = "viperboard gpio b";
0414 vb_gpio->gpiob.parent = &pdev->dev;
0415 vb_gpio->gpiob.owner = THIS_MODULE;
0416 vb_gpio->gpiob.base = -1;
0417 vb_gpio->gpiob.ngpio = 16;
0418 vb_gpio->gpiob.can_sleep = true;
0419 vb_gpio->gpiob.set = vprbrd_gpiob_set;
0420 vb_gpio->gpiob.get = vprbrd_gpiob_get;
0421 vb_gpio->gpiob.direction_input = vprbrd_gpiob_direction_input;
0422 vb_gpio->gpiob.direction_output = vprbrd_gpiob_direction_output;
0423
0424 return devm_gpiochip_add_data(&pdev->dev, &vb_gpio->gpiob, vb_gpio);
0425 }
0426
0427 static struct platform_driver vprbrd_gpio_driver = {
0428 .driver.name = "viperboard-gpio",
0429 .probe = vprbrd_gpio_probe,
0430 };
0431
0432 static int __init vprbrd_gpio_init(void)
0433 {
0434 switch (gpioa_freq) {
0435 case 1000000:
0436 gpioa_clk = VPRBRD_GPIOA_CLK_1MHZ;
0437 break;
0438 case 100000:
0439 gpioa_clk = VPRBRD_GPIOA_CLK_100KHZ;
0440 break;
0441 case 10000:
0442 gpioa_clk = VPRBRD_GPIOA_CLK_10KHZ;
0443 break;
0444 case 1000:
0445 gpioa_clk = VPRBRD_GPIOA_CLK_1KHZ;
0446 break;
0447 case 100:
0448 gpioa_clk = VPRBRD_GPIOA_CLK_100HZ;
0449 break;
0450 case 10:
0451 gpioa_clk = VPRBRD_GPIOA_CLK_10HZ;
0452 break;
0453 default:
0454 pr_warn("invalid gpioa_freq (%d)\n", gpioa_freq);
0455 gpioa_clk = VPRBRD_GPIOA_CLK_1KHZ;
0456 }
0457
0458 return platform_driver_register(&vprbrd_gpio_driver);
0459 }
0460 subsys_initcall(vprbrd_gpio_init);
0461
0462 static void __exit vprbrd_gpio_exit(void)
0463 {
0464 platform_driver_unregister(&vprbrd_gpio_driver);
0465 }
0466 module_exit(vprbrd_gpio_exit);
0467
0468 MODULE_AUTHOR("Lars Poeschel <poeschel@lemonage.de>");
0469 MODULE_DESCRIPTION("GPIO driver for Nano River Techs Viperboard");
0470 MODULE_LICENSE("GPL");
0471 MODULE_ALIAS("platform:viperboard-gpio");