Beispiel #1
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("BT_ioctl(): cmd (%d)\n", cmd);

	switch (cmd) {
#if 0
	case 0:		/* enable/disable STP */
		/* George: STP is controlled by WMT only */
		/* mtk_wcn_stp_enable(arg); */
		break;
#endif
	case 1:		/* send raw data */
		BT_DBG_FUNC("BT_ioctl(): disable raw data from BT dev\n");
		retval = -EINVAL;
		break;
	case COMBO_IOC_BT_HWVER:
		/*get combo hw version */
		hw_ver_sym = mtk_wcn_wmt_hwver_get();

		BT_INFO_FUNC("BT_ioctl(): 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_IOCTL_FW_ASSERT:
		/* BT trigger fw assert for debug */
		BT_INFO_FUNC("BT Set fw assert......, reason:%lu\n", arg);
		bRet = mtk_wcn_wmt_assert(WMTDRV_TYPE_BT, arg);
		if (bRet == MTK_WCN_BOOL_TRUE) {
			BT_INFO_FUNC("BT Set fw assert OK\n");
			retval = 0;
		} else {
			BT_INFO_FUNC("BT Set fw assert Failed\n");
			retval = (-1000);
		}
		break;
	case COMBO_IOCTL_BT_IC_HW_VER:
		return mtk_wcn_wmt_ic_info_get(WMTCHIN_HWVER);
		break;
	case COMBO_IOCTL_BT_IC_FW_VER:
		return mtk_wcn_wmt_ic_info_get(WMTCHIN_FWVER);
		break;
	default:
		retval = -EFAULT;
		BT_DBG_FUNC("BT_ioctl(): unknown cmd (%d)\n", cmd);
		break;
	}

	return retval;
}
Beispiel #2
0
static VOID bt_cdev_rst_cb(ENUM_WMTDRV_TYPE_T src,
			   ENUM_WMTDRV_TYPE_T dst, ENUM_WMTMSG_TYPE_T type, PVOID buf, UINT32 sz)
{
	/*
	   Handle whole chip reset messages
	 */
	ENUM_WMTRSTMSG_TYPE_T rst_msg;

	if (sz <= sizeof(ENUM_WMTRSTMSG_TYPE_T)) {
		memcpy((PINT8) & rst_msg, (PINT8) buf, sz);
		BT_DBG_FUNC("src = %d, dst = %d, type = %d, buf = 0x%x sz = %d, max = %d\n", src,
			     dst, type, rst_msg, sz, WMTRSTMSG_RESET_MAX);
		if ((src == WMTDRV_TYPE_WMT) && (dst == WMTDRV_TYPE_BT)
		    && (type == WMTMSG_TYPE_RESET)) {
			if (rst_msg == WMTRSTMSG_RESET_START) {
				BT_INFO_FUNC("BT reset start!\n");
				rstflag = 1;
				wake_up_interruptible(&inq);

			} else if (rst_msg == WMTRSTMSG_RESET_END) {
				BT_INFO_FUNC("BT reset end!\n");
				rstflag = 2;
				wake_up_interruptible(&inq);
			}
		}
	} else {
		/* Invalid message format */
		BT_WARN_FUNC("Invalid message format!\n");
	}
}
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 #4
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 #5
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;
}
void BT_event_cb(void)
{
    BT_DBG_FUNC("BT_event_cb() \n");

    flag = 1;
    wake_up(&BT_wq);

    /* finally, awake any reader */
    wake_up_interruptible(&inq);  /* blocked in read() and select() */

    return;
}
Beispiel #7
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;
}
Beispiel #8
0
VOID BT_event_cb(VOID)
{
	BT_DBG_FUNC("BT_event_cb()\n");

	flag = 1;

	/*
	* Finally, wake up any reader blocked in poll or read
	*/
	wake_up_interruptible(&inq);
	wake_up(&BT_wq);
}
Beispiel #9
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;
}
ssize_t BT_read(struct file *filp, char __user *buf, size_t count, loff_t *f_pos)
{
    int retval = 0;

    down(&rd_mtx);

    BT_DBG_FUNC("BT_read(): count %d 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 > MTKSTP_BUFFER_SIZE)
    {
        count = MTKSTP_BUFFER_SIZE;
    }
    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);
}
//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)
{
    int retval = 0;


    ENUM_WMTHWVER_TYPE_T hw_ver_sym = WMTHWVER_INVALID;
    BT_DBG_FUNC("BT_ioctl(): cmd (%d)\n", cmd);

    switch(cmd)
    {
#if 0
        case 0: // enable/disable STP
            /* George: STP is controlled by WMT only */
            /* mtk_wcn_stp_enable(arg); */
            break;
#endif
        case 1: // send raw data
            BT_DBG_FUNC("BT_ioctl(): disable raw data from BT dev \n");
            retval = -EINVAL;
            break;
        case COMBO_IOC_BT_HWVER:
            /*get combo hw version*/
            hw_ver_sym = mtk_wcn_wmt_hwver_get();

            BT_INFO_FUNC("BT_ioctl(): get hw version = %d, sizeof(hw_ver_sym) = %d\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;
        default:
            retval = -EFAULT;
            BT_DBG_FUNC("BT_ioctl(): unknown cmd (%d)\n", cmd);
            break;
    }

    return retval;
}
Beispiel #12
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;
}