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;
}
Esempio n. 2
0
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;
}