ssize_t BT_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos)
{
    int retval = 0;
    int written = 0;
    down(&wr_mtx);

    BT_DBG_FUNC("%s: count %d pos %lld\n", __func__, count, *f_pos);
    if(retflag)
    {
        if (retflag == 1) //reset start
        {
            retval = -88;
            BT_INFO_FUNC("MT662x reset Write: start\n");
        }
        else if (retflag == 2) // reset end
        {
          retval = -99;
            BT_INFO_FUNC("MT662x reset Write: end\n");
        }
    goto OUT;
    }

    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);

        written = mtk_wcn_stp_send_data(&o_buf[0], copy_size, BT_TASK_INDX);
        if(0 == written)
        {
            retval = -ENOSPC;
            /*no windowspace in STP is available, native process should not call BT_write with no delay at all*/
            BT_ERR_FUNC("target packet length:%d, write success length:%d, retval = %d.\n", count, written, retval);
        }
        else
        {
            retval = written;
        }

    }else
    {
        retval = -EFAULT;
        BT_ERR_FUNC("target packet length:%d is not allowed, retval = %d.\n", count, retval);
    }

OUT:
    up(&wr_mtx);
    return (retval);
}
Beispiel #2
0
ssize_t BT_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos)
{
	INT32 retval = 0;
	INT32 written = 0;
	down(&wr_mtx);

	BT_DBG_FUNC("%s: count %zd pos %lld\n", __func__, count, *f_pos);
	if (retflag) {
		if (retflag == 1) {	/* reset start */
			retval = -88;
			BT_INFO_FUNC("MT662x reset Write: start\n");
		} else if (retflag == 2) {	/* reset end */
			retval = -99;
			BT_INFO_FUNC("MT662x reset Write: end\n");
		}
		goto OUT;
	}

	if (count > 0) {
		INT32 copy_size;

		if (count < BT_BUFFER_SIZE) {
			copy_size = count;
		} else {
			copy_size = BT_BUFFER_SIZE;
			BT_ERR_FUNC(" count > BT_BUFFER_SIZE\n");
		}

		if (copy_from_user(&o_buf[0], &buf[0], copy_size)) {
			retval = -EFAULT;
			goto OUT;
		}
		/* pr_warn("%02x ", val); */

		written = mtk_wcn_stp_send_data(&o_buf[0], copy_size, BT_TASK_INDX);
		if (0 == written) {
			retval = -ENOSPC;
			/*no windowspace is available, native process should not call BT_write with no delay at all */
			BT_ERR_FUNC
			    ("target packet length:%zd, write success length:%d, retval = %d.\n",
			     count, written, retval);
		} else {
			retval = written;
		}

	} else {
		retval = -EFAULT;
		BT_ERR_FUNC("target packet length:%zd is not allowed, retval = %d.\n", count, retval);
	}

OUT:
	up(&wr_mtx);
	return retval;
}
Beispiel #3
0
ssize_t BT_write(struct file *filp, const char __user *buf, size_t count, loff_t *f_pos)
{
	INT32 retval = 0;
	INT32 write_size;
	INT32 written = 0;

	down(&wr_mtx);

	BT_DBG_FUNC("%s: count %zd pos %lld\n", __func__, count, *f_pos);
	if (rstflag) {
		if (rstflag == 1) {	/* Reset start */
			retval = -88;
			BT_INFO_FUNC("%s: detect whole chip reset start\n", __func__);
		} else if (rstflag == 2) {	/* Reset end */
			retval = -99;
			BT_INFO_FUNC("%s: detect whole chip reset end\n", __func__);
		}
		goto OUT;
	}

	if (count > 0) {
		if (count < BT_BUFFER_SIZE) {
			write_size = count;
		} else {
			write_size = BT_BUFFER_SIZE;
			BT_ERR_FUNC("%s: count > BT_BUFFER_SIZE\n", __func__);
		}

		if (copy_from_user(&o_buf[0], &buf[0], write_size)) {
			retval = -EFAULT;
			goto OUT;
		}

		written = mtk_wcn_stp_send_data(&o_buf[0], write_size, BT_TASK_INDX);
		if (0 == written) {
			retval = -ENOSPC;
			/* No space is available, native program should not call BT_write with no delay */
			BT_ERR_FUNC
			    ("Packet length %zd, sent length %d, retval = %d\n",
			     count, written, retval);
		} else {
			retval = written;
		}

	} else {
		retval = -EFAULT;
		BT_ERR_FUNC("Packet length %zd is not allowed, retval = %d\n", count, retval);
	}

OUT:
	up(&wr_mtx);
	return retval;
}
static int BT_open(struct inode *inode, struct file *file)
{
    BT_INFO_FUNC("%s: major %d minor %d (pid %d)\n", __func__,
        imajor(inode),
        iminor(inode),
        current->pid
        );

#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_BT)) {
        BT_WARN_FUNC("WMT turn on BT fail!\n");
        return -ENODEV;
    }else{
        retflag = 0;
        mtk_wcn_wmt_msgcb_reg(WMTDRV_TYPE_BT, bt_cdev_rst_cb);
        BT_INFO_FUNC("WMT register BT rst cb!\n");
    }
#endif

    if (mtk_wcn_stp_is_ready()) {
#if 0 /* GeorgeKuo: turn on function before check stp ready */
         /* turn on BT */
        if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_on(WMTDRV_TYPE_BT)) {
            BT_WARN_FUNC("WMT turn on BT fail!\n");
            return -ENODEV;
        }
#endif
        mtk_wcn_stp_set_bluez(0);

        BT_INFO_FUNC("Now it's in MTK Bluetooth Mode\n");
        BT_INFO_FUNC("WMT turn on BT OK!\n");
        BT_INFO_FUNC("STP is ready!\n");
        platform_load_nvram_data(BT_NVRAM_CUSTOM_NAME,
            (char *)&g_nvram_btdata, sizeof(g_nvram_btdata));

        BT_INFO_FUNC("Read NVRAM : BD address %02x%02x%02x%02x%02x%02x Cap 0x%02x Codec 0x%02x\n",
            g_nvram_btdata[0], g_nvram_btdata[1], g_nvram_btdata[2],
            g_nvram_btdata[3], g_nvram_btdata[4], g_nvram_btdata[5],
            g_nvram_btdata[6], g_nvram_btdata[7]);

        mtk_wcn_stp_register_event_cb(BT_TASK_INDX, BT_event_cb);
		BT_INFO_FUNC("mtk_wcn_stp_register_event_cb finish\n");
    }
    else {
        BT_ERR_FUNC("STP is not ready\n");

        /*return error code*/
        return -ENODEV;
    }

//    init_MUTEX(&wr_mtx);
    sema_init(&wr_mtx, 1);
//    init_MUTEX(&rd_mtx);
    sema_init(&rd_mtx, 1);
	BT_INFO_FUNC("finish\n");

    return 0;
}
Beispiel #5
0
static int BT_init(void)
{
	dev_t dev = MKDEV(BT_major, 0);
	INT32 alloc_ret = 0;
	INT32 cdev_err = 0;
#if REMOVE_MK_NODE
	struct device *stpbt_dev = NULL;
#endif

	/*static allocate chrdev */
	alloc_ret = register_chrdev_region(dev, 1, BT_DRIVER_NAME);
	if (alloc_ret) {
		BT_ERR_FUNC("fail to register chrdev\n");
		return alloc_ret;
	}

	cdev_init(&BT_cdev, &BT_fops);
	BT_cdev.owner = THIS_MODULE;

	cdev_err = cdev_add(&BT_cdev, dev, BT_devs);
	if (cdev_err)
		goto error;
#if REMOVE_MK_NODE		/* mknod replace */

	stpbt_class = class_create(THIS_MODULE, "stpbt");
	if (IS_ERR(stpbt_class))
		goto error;
	stpbt_dev = device_create(stpbt_class, NULL, dev, NULL, "stpbt");
	if (IS_ERR(stpbt_dev))
		goto error;
#endif

	BT_INFO_FUNC("%s driver(major %d) installed.\n", BT_DRIVER_NAME, BT_major);
	retflag = 0;
	mtk_wcn_stp_register_event_cb(BT_TASK_INDX, NULL);

	/* init wait queue */
	init_waitqueue_head(&(inq));

	return 0;

error:

#if REMOVE_MK_NODE
	if (!IS_ERR(stpbt_dev))
		device_destroy(stpbt_class, dev);
	if (!IS_ERR(stpbt_class)) {
		class_destroy(stpbt_class);
		stpbt_class = NULL;
	}
#endif
	if (cdev_err == 0)
		cdev_del(&BT_cdev);

	if (alloc_ret == 0)
		unregister_chrdev_region(dev, BT_devs);

	return -1;
}
Beispiel #6
0
ssize_t BT_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
{
	static int chip_reset_count;
	INT32 retval = 0;

	down(&rd_mtx);

	BT_DBG_FUNC("%s: count %zd pos %lld\n", __func__, count, *f_pos);
	if (rstflag) {
		if (rstflag == 1) {	/* Reset start */
			retval = -88;
			if ((chip_reset_count%500) == 0)
				BT_INFO_FUNC("%s: detect whole chip reset start, %d\n", __func__, chip_reset_count);
			chip_reset_count++;
		} else if (rstflag == 2) {	/* Reset end */
			retval = -99;
			BT_INFO_FUNC("%s: detect whole chip reset end\n", __func__);
			chip_reset_count = 0;
		}
		goto OUT;
	}

	if (count > BT_BUFFER_SIZE) {
		count = BT_BUFFER_SIZE;
		BT_ERR_FUNC("%s: count > BT_BUFFER_SIZE\n", __func__);
	}

	retval = mtk_wcn_stp_receive_data(i_buf, count, BT_TASK_INDX);

	while (retval == 0) {	/* Got nothing, wait for STP's signal */
		/*
		* If nonblocking mode, return directly.
		* O_NONBLOCK is specified during open()
		*/
		if (filp->f_flags & O_NONBLOCK) {
			BT_DBG_FUNC("Non-blocking BT_read\n");
			retval = -EAGAIN;
			goto OUT;
		}

		BT_DBG_FUNC("%s: wait_event 1\n", __func__);
		wait_event(BT_wq, flag != 0);
		BT_DBG_FUNC("%s: wait_event 2\n", __func__);
		flag = 0;
		retval = mtk_wcn_stp_receive_data(i_buf, count, BT_TASK_INDX);
		BT_DBG_FUNC("%s: mtk_wcn_stp_receive_data returns %d\n", __func__, retval);
	}

	/* Got something from STP driver */
	if (copy_to_user(buf, i_buf, retval)) {
		retval = -EFAULT;
		goto OUT;
	}

OUT:
	up(&rd_mtx);
	BT_DBG_FUNC("%s: retval = %d\n", __func__, retval);
	return retval;
}
static int nvram_read(char *filename, char *buf, ssize_t len, int offset)
{
    struct file *fd;
    //ssize_t ret;
    int retLen = -1;

    mm_segment_t old_fs = get_fs();
    set_fs(KERNEL_DS);

    fd = filp_open(filename, O_WRONLY|O_CREAT, 0644);

    if(IS_ERR(fd)) {
        BT_ERR_FUNC("failed to open!!\n");
        return -1;
    }
    do{
        if ((fd->f_op == NULL) || (fd->f_op->read == NULL))
            {
            BT_ERR_FUNC("file can not be read!!\n");
            break;
            }

        if (fd->f_pos != offset) {
            if (fd->f_op->llseek) {
                    if(fd->f_op->llseek(fd, offset, 0) != offset) {
                        BT_ERR_FUNC("[nvram_read] : failed to seek!!\n");
                        break;
                    }
              } else {
                    fd->f_pos = offset;
              }
        }

            retLen = fd->f_op->read(fd,
                                          buf,
                                          len,
                                          &fd->f_pos);

    }while(false);

    filp_close(fd, NULL);

    set_fs(old_fs);

    return retLen;
}
Beispiel #8
0
/* int BT_ioctl(struct inode *inode, struct file *filp, unsigned int cmd, unsigned long arg) */
long BT_unlocked_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
	INT32 retval = 0;
	MTK_WCN_BOOL bRet = MTK_WCN_BOOL_TRUE;
	ENUM_WMTHWVER_TYPE_T hw_ver_sym = WMTHWVER_INVALID;

	BT_DBG_FUNC("%s:  cmd: 0x%x\n", __func__, cmd);

	switch (cmd) {
	case COMBO_IOC_BT_HWVER:
		/* Get combo HW version */
		hw_ver_sym = mtk_wcn_wmt_hwver_get();
		BT_INFO_FUNC("%s: HW version = %d, sizeof(hw_ver_sym) = %zd\n",
			     __func__, 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_IOCTL_FW_ASSERT:
		/* Trigger FW assert for debug */
		BT_INFO_FUNC("%s: Host trigger FW assert......, reason:%lu\n", __func__, arg);
		bRet = mtk_wcn_wmt_assert(WMTDRV_TYPE_BT, arg);
		if (bRet == MTK_WCN_BOOL_TRUE) {
			BT_INFO_FUNC("Host trigger FW assert succeed\n");
			retval = 0;
		} else {
			BT_ERR_FUNC("Host trigger FW assert Failed\n");
			retval = (-EBUSY);
		}
		break;
	case COMBO_IOCTL_BT_IC_HW_VER:
		retval = mtk_wcn_wmt_ic_info_get(WMTCHIN_HWVER);
		break;
	case COMBO_IOCTL_BT_IC_FW_VER:
		retval = mtk_wcn_wmt_ic_info_get(WMTCHIN_FWVER);
		break;
	default:
		retval = -EFAULT;
		BT_ERR_FUNC("Unknown cmd (%d)\n", cmd);
		break;
	}

	return retval;
}
Beispiel #9
0
ssize_t BT_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
{
	INT32 retval = 0;

	down(&rd_mtx);

	BT_DBG_FUNC("BT_read(): count %zd pos %lld\n", count, *f_pos);
	if (retflag) {
		if (retflag == 1) {	/* reset start */
			retval = -88;
			BT_INFO_FUNC("MT662x reset Read: start\n");
		} else if (retflag == 2) {	/* reset end */
			retval = -99;
			BT_INFO_FUNC("MT662x reset Read: end\n");
		}
		goto OUT;
	}

	if (count > BT_BUFFER_SIZE) {
		count = BT_BUFFER_SIZE;
		BT_ERR_FUNC(" count > BT_BUFFER_SIZE\n");
	}

	retval = mtk_wcn_stp_receive_data(i_buf, count, BT_TASK_INDX);

	while (retval == 0) {	/* got nothing, wait for STP's signal */
		/*If nonblocking mode, return directly O_NONBLOCK is specified during open() */
		if (filp->f_flags & O_NONBLOCK) {
			BT_DBG_FUNC("Non-blocking BT_read()\n");
			retval = -EAGAIN;
			goto OUT;
		}

		BT_DBG_FUNC("BT_read(): wait_event 1\n");
		wait_event(BT_wq, flag != 0);
		BT_DBG_FUNC("BT_read(): wait_event 2\n");
		flag = 0;
		retval = mtk_wcn_stp_receive_data(i_buf, count, BT_TASK_INDX);
		BT_DBG_FUNC("BT_read(): mtk_wcn_stp_receive_data() = %d\n", retval);
	}

	/* we got something from STP driver */
	if (copy_to_user(buf, i_buf, retval)) {
		retval = -EFAULT;
		goto OUT;
	}

OUT:
	up(&rd_mtx);
	BT_DBG_FUNC("BT_read(): retval = %d\n", retval);
	return retval;
}
Beispiel #10
0
static int BT_close(struct inode *inode, struct file *file)
{
	BT_INFO_FUNC("%s: major %d minor %d pid %d\n", __func__, imajor(inode), iminor(inode), current->pid);
	if (current->pid == 1)
		return 0;

	rstflag = 0;
	mtk_wcn_wmt_msgcb_unreg(WMTDRV_TYPE_BT);
	mtk_wcn_stp_register_event_cb(BT_TASK_INDX, NULL);

	if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_off(WMTDRV_TYPE_BT)) {
		BT_ERR_FUNC("WMT turn off BT fail!\n");
		return -EIO;	/* Mostly, native program will not check this return value. */
	}

	BT_INFO_FUNC("WMT turn off BT OK!\n");
	return 0;
}
Beispiel #11
0
static int BT_open(struct inode *inode, struct file *file)
{
	BT_INFO_FUNC("%s: major %d minor %d pid %d\n", __func__, imajor(inode), iminor(inode), current->pid);
	if (current->pid == 1)
		return 0;

	/* Turn on BT */
	if (MTK_WCN_BOOL_FALSE == mtk_wcn_wmt_func_on(WMTDRV_TYPE_BT)) {
		BT_WARN_FUNC("WMT turn on BT fail!\n");
		return -ENODEV;
	}

	BT_INFO_FUNC("WMT turn on BT OK!\n");
	rstflag = 0;

	if (mtk_wcn_stp_is_ready()) {

		mtk_wcn_stp_set_bluez(0);

		BT_INFO_FUNC("Now it's in MTK Bluetooth Mode\n");
		BT_INFO_FUNC("STP is ready!\n");

		BT_DBG_FUNC("Register BT event callback!\n");
		mtk_wcn_stp_register_event_cb(BT_TASK_INDX, BT_event_cb);
	} else {
		BT_ERR_FUNC("STP is not ready\n");
		mtk_wcn_wmt_func_off(WMTDRV_TYPE_BT);
		return -ENODEV;
	}

	BT_DBG_FUNC("Register BT reset callback!\n");
	mtk_wcn_wmt_msgcb_reg(WMTDRV_TYPE_BT, bt_cdev_rst_cb);

/* init_MUTEX(&wr_mtx); */
	sema_init(&wr_mtx, 1);
/* init_MUTEX(&rd_mtx); */
	sema_init(&rd_mtx, 1);
	BT_INFO_FUNC("%s: finish\n", __func__);

	return 0;
}
Beispiel #12
0
static int BT_init(void)
{
	dev_t dev = MKDEV(BT_major, 0);
	int alloc_ret = 0;
	int cdev_err = 0;

/*static allocate chrdev*/
	alloc_ret = register_chrdev_region(dev, 1, BT_DRIVER_NAME);
	if (alloc_ret) {
		BT_ERR_FUNC("fail to register chrdev\n");
		return alloc_ret;
	}

	cdev_init(&BT_cdev, &BT_fops);
	BT_cdev.owner = THIS_MODULE;

	cdev_err = cdev_add(&BT_cdev, dev, BT_devs);
	if (cdev_err)
		goto error;

	BT_INFO_FUNC("%s driver(major %d) installed.\n",
		     BT_DRIVER_NAME, BT_major);
	retflag = 0;
	mtk_wcn_stp_register_event_cb(BT_TASK_INDX, NULL);

/* init wait queue */
	init_waitqueue_head(&(inq));

	return 0;

error:
	if (cdev_err == 0)
		cdev_del(&BT_cdev);

	if (alloc_ret == 0)
		unregister_chrdev_region(dev, BT_devs);

	return -1;
}