ssize_t GPS_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos) { int retval = 0; int written = 0; down(&wr_mtx); /* GPS_TRC_FUNC(); */ /*printk("%s: count %d pos %lld\n", __func__, count, *f_pos); */ if (count > 0) { int copy_size = (count < MTKSTP_BUFFER_SIZE) ? count : MTKSTP_BUFFER_SIZE; if (copy_from_user(&o_buf[0], &buf[0], copy_size)) { retval = -EFAULT; goto out; } /* printk("%02x ", val); */ #if GPS_DEBUG_TRACE_GPIO mtk_wcn_stp_debug_gpio_assert(IDX_GPS_TX, DBG_TIE_LOW); #endif written = mtk_wcn_stp_send_data(&o_buf[0], copy_size, GPS_TASK_INDX); #if GPS_DEBUG_TRACE_GPIO mtk_wcn_stp_debug_gpio_assert(IDX_GPS_TX, DBG_TIE_HIGH); #endif #if GPS_DEBUG_DUMP { unsigned char *buf_ptr = &o_buf[0]; int k = 0; pr_debug("--[GPS-WRITE]--"); for (k = 0; k < 10; k++) { if (k % 16 == 0) pr_debug("\n"); pr_debug("0x%02x ", o_buf[k]); } pr_debug("\n"); } #endif /* If cannot send successfully, enqueue again if (written != copy_size) { // George: FIXME! Move GPS retry handling from app to driver } */ if (0 == written) { retval = -ENOSPC; /*no windowspace in STP is available, native process should not call GPS_write with no delay at all */ GPS_ERR_FUNC("target packet length:%zd, write success length:%d, retval = %d.\n", count, written, retval); } else { retval = written; } } else { retval = -EFAULT; GPS_ERR_FUNC("target packet length:%zd is not allowed, retval = %d.\n", count, retval); } out: up(&wr_mtx); return retval; }
static int GPS_open(struct inode *inode, struct file *file) { printk("%s: major %d minor %d (pid %d)\n", __func__, imajor(inode), iminor(inode), current->pid ); if(retflag == 1) { GPS_WARN_FUNC("whole chip resetting...\n"); return -EPERM; } #if 1 /* GeorgeKuo: turn on function before check stp ready */ /* turn on BT */ if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_on(WMTDRV_TYPE_GPS)) { GPS_WARN_FUNC("WMT turn on GPS fail!\n"); return -ENODEV; } else { mtk_wcn_wmt_msgcb_reg(WMTDRV_TYPE_GPS, gps_cdev_rst_cb); GPS_INFO_FUNC("WMT turn on GPS OK!\n"); } #endif if (mtk_wcn_stp_is_ready()) { #if 0 if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_on(WMTDRV_TYPE_GPS)) { GPS_WARN_FUNC("WMT turn on GPS fail!\n"); return -ENODEV; } GPS_INFO_FUNC("WMT turn on GPS OK!\n"); #endif mtk_wcn_stp_register_event_cb(GPS_TASK_INDX, GPS_event_cb); } else { GPS_ERR_FUNC("STP is not ready, Cannot open GPS Devices\n\r"); /*return error code*/ return -ENODEV; } //init_MUTEX(&wr_mtx); sema_init(&wr_mtx, 1); //init_MUTEX(&rd_mtx); sema_init(&rd_mtx, 1); return 0; }
static int GPS_init(void) { dev_t dev = MKDEV(GPS_major, 0); int alloc_ret = 0; int cdev_err = 0; /*static allocate chrdev*/ alloc_ret = register_chrdev_region(dev, 1, GPS_DRIVER_NAME); if (alloc_ret) { printk("fail to register chrdev\n"); return alloc_ret; } cdev_init(&GPS_cdev, &GPS_fops); GPS_cdev.owner = THIS_MODULE; cdev_err = cdev_add(&GPS_cdev, dev, GPS_devs); if (cdev_err) goto error; printk(KERN_ALERT "%s driver(major %d) installed.\n", GPS_DRIVER_NAME, GPS_major); #if 1 cls = class_create(THIS_MODULE, "stpgpsdrv"); if (IS_ERR(cls)) { GPS_ERR_FUNC("Unable to create class, err = %d\n", (int)PTR_ERR(cls)); goto error; } device_create(cls,NULL,dev,NULL,"stpgps"); #endif return 0; error: if (cdev_err == 0) cdev_del(&GPS_cdev); if (alloc_ret == 0) unregister_chrdev_region(dev, GPS_devs); return -1; }
/* int GPS_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) */ long GPS_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) { int retval = 0; ENUM_WMTHWVER_TYPE_T hw_ver_sym = WMTHWVER_INVALID; pr_debug("GPS_ioctl(): cmd (%d)\n", cmd); switch (cmd) { case 0: /* enable/disable STP */ GPS_INFO_FUNC("disable STP control from GPS dev\n"); retval = -EINVAL; #if 1 #else /* George: STP is controlled by WMT only */ mtk_wcn_stp_enable(arg); #endif break; case 1: /* send raw data */ GPS_INFO_FUNC("disable raw data from GPS dev\n"); retval = -EINVAL; break; case COMBO_IOC_GPS_HWVER: /*get combo hw version */ hw_ver_sym = mtk_wcn_wmt_hwver_get(); GPS_INFO_FUNC("get hw version = %d, sizeof(hw_ver_sym) = %zd\n", hw_ver_sym, sizeof(hw_ver_sym)); if (copy_to_user((int __user *)arg, &hw_ver_sym, sizeof(hw_ver_sym))) retval = -EFAULT; break; case COMBO_IOC_RTC_FLAG: retval = rtc_GPS_low_power_detected(); GPS_INFO_FUNC("low power flag (%d)\n", retval); break; case COMBO_IOC_CO_CLOCK_FLAG: retval = mtk_wcn_wmt_co_clock_flag_get(); GPS_INFO_FUNC("GPS co_clock_flag (%d)\n", retval); break; case COMBO_IOC_D1_EFUSE_GET: #if defined(CONFIG_ARCH_MT6735) do { char *addr = ioremap(0x10206198, 0x4); retval = *(volatile unsigned int *)addr; GPS_INFO_FUNC("D1 efuse (0x%x)\n", retval); iounmap(addr); } while (0); #else GPS_ERR_FUNC("Read Efuse not supported in this platform\n"); #endif break; default: retval = -EFAULT; GPS_INFO_FUNC("unknown cmd (%d)\n", cmd); break; } /*OUT:*/ return retval; }