/* * GSC3280 GW-JZQ GPRS Driver * * Copyright (C) 2013 BLX IC Design Corp.,Ltd. * Author: Fei Lu, Lufei@china-cpu.com * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include enum { GPRS_VCCON = 0, GPRS_VCCOFF, GPRS_POWERON, GPRS_POWEROFF, GPRS_RESET, GPRS_PCTRLON, GPRS_PCTRLOFF, GPRS_GET_STATUS, }; enum { VCC = 0, POWER, PCTRL, /* RESET, S0, S1, S2, S3, S4, */ MAX_PIN_NR, }; struct gpio gprs_gpios[MAX_PIN_NR] = { {GSC3280_GPC(20), GPIOF_OUT_INIT_LOW, "GPRS VCC ON/OFF"}, {GSC3280_GPB(26), GPIOF_OUT_INIT_HIGH, "GPRS POWER ON/OFF"}, {GSC3280_GPB(27), GPIOF_OUT_INIT_LOW, "GPRS PCTRL ON/OFF"}, /* {GSC3280_GPA(3), GPIOF_OUT_INIT_HIGH, "GPRS RESET"}, {GSC3280_GPA(4), GPIOF_IN, "GPRS S0"}, {GSC3280_GPA(5), GPIOF_IN, "GPRS S1"}, {GSC3280_GPB(20), GPIOF_IN, "GPRS S2"}, {GSC3280_GPB(21), GPIOF_IN, "GPRS S3"}, {GSC3280_GPA(17), GPIOF_IN, "GPRS S4"} */ }; struct jzq_gprs { struct cdev cdev; struct class *gprs_class; dev_t dev; }; struct jzq_gprs jzq_gprs_priv; static long gprs_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { switch(cmd) { case GPRS_VCCON: gpio_set_value(gprs_gpios[VCC].gpio, 1); break; case GPRS_VCCOFF: gpio_set_value(gprs_gpios[VCC].gpio, 0); break; case GPRS_POWERON: gpio_set_value(gprs_gpios[POWER].gpio, 0); msleep(1000); gpio_set_value(gprs_gpios[POWER].gpio, 1); break; case GPRS_POWEROFF: gpio_set_value(gprs_gpios[POWER].gpio, 0); msleep(3000); gpio_set_value(gprs_gpios[POWER].gpio, 1); break; case GPRS_PCTRLON: gpio_set_value(gprs_gpios[PCTRL].gpio, 1); break; case GPRS_PCTRLOFF: gpio_set_value(gprs_gpios[PCTRL].gpio, 0); break; case GPRS_RESET: /* gpio_set_value(gprs_gpios[RESET].gpio, 0); msleep(200); gpio_set_value(gprs_gpios[RESET].gpio, 1); */ break; case GPRS_GET_STATUS: //gpio_set_value(gprs_gpios[S0].gpio); break; default: return -ENOTTY; } return 0; } static int gprs_open(struct inode *inode, struct file *filp) { return 0; } static int gprs_release(struct inode *inode, struct file *filp) { return 0; } struct file_operations gprs_fops = { .owner = THIS_MODULE, .unlocked_ioctl = gprs_ioctl, .open = gprs_open, .release = gprs_release, }; static int __init jzq_gprs_init(void) { int err,ret; int result; int major; result = alloc_chrdev_region(&jzq_gprs_priv.dev, 0, 0, "gprs"); major = MAJOR(jzq_gprs_priv.dev); if (result < 0) { printk(KERN_WARNING "jzq_gprs: can't get major %d\n", major); return result; } cdev_init(&jzq_gprs_priv.cdev, &gprs_fops); jzq_gprs_priv.cdev.owner = THIS_MODULE; jzq_gprs_priv.cdev.ops = &gprs_fops; err = cdev_add(&jzq_gprs_priv.cdev, jzq_gprs_priv.dev, 1); if (err) { printk(KERN_NOTICE "Error[%d] cdev_add .\n", err); return -1; } jzq_gprs_priv.gprs_class = class_create(THIS_MODULE, "gprs"); if (IS_ERR(jzq_gprs_priv.gprs_class)) { printk(KERN_ERR "Failed in create gprs_cdev class\n"); return -1; } device_create(jzq_gprs_priv.gprs_class, NULL, jzq_gprs_priv.dev, NULL, "gprs"); ret = gpio_request_array(gprs_gpios, MAX_PIN_NR); if (ret < 0) return ret; return 0; } static void __exit jzq_gprs_exit(void) { gpio_free_array(gprs_gpios, MAX_PIN_NR); cdev_del(&jzq_gprs_priv.cdev); unregister_chrdev_region(jzq_gprs_priv.dev, 1); device_destroy(jzq_gprs_priv.gprs_class, jzq_gprs_priv.dev); class_destroy(jzq_gprs_priv.gprs_class); } module_init(jzq_gprs_init); module_exit(jzq_gprs_exit); MODULE_AUTHOR("lufei@china-cpu.com"); MODULE_DESCRIPTION("GSC3280 GW-JZQ GPRS Driver"); MODULE_LICENSE("GPL");