Beispiel #1
0
static inline int bma250_range_handler(struct driver_data *dd)
{
	int rc = 0;
	u8 range, threshold, duration = 0;

	if (dd->new_cnf.range == dd->cur_cnf.range)
		return rc;

	if (dd->new_cnf.range == 16) {
		range = BMA250_RANGE_16G;
		threshold = 2;
	} else if (dd->new_cnf.range == 8) {
		range = BMA250_RANGE_8G;
		threshold = 3;
	} else if (dd->new_cnf.range == 4) {
		range = BMA250_RANGE_4G;
		threshold = 4;
	} else {
		range = BMA250_RANGE_2G;
		threshold = 5;
	}
	rc = bma250_ic_write(dd->ic_dev, BMA250_RANGE_REG, range);
	if (rc)
		goto range_error;

	/* threshold definition for the slope int, g-range dependant */
	rc = bma250_ic_write(dd->ic_dev, BMA250_SLOPE_THR, threshold);
	if (rc)
		goto range_error;

	/* number of samples (n + 1) to be evaluted for slope int */
	rc = bma250_ic_write(dd->ic_dev, BMA250_SLOPE_DUR, duration);
	if (rc)
		goto range_error;

	dd->shift = bma250_range2shift(range);
	dd->cur_cnf.range = dd->new_cnf.range;
	return rc;

range_error:
	dev_err(&dd->ip_dev->dev,
		"%s: device failed, error %d\n", __func__, rc);
	return rc;
}
Beispiel #2
0
static ssize_t bma250_dbfs_write(struct file *fp, const char __user *buf,
                                 size_t count, loff_t *f_pos)
{
    u8                          *p;
    u8                          *np;
    u8                          *mbuf;
    int                          rc;
    unsigned int                 val;
    u8                           reg;
    u8                           data;
    struct driver_data          *dd;

    /* format of write data is "A[A] D[D]" eg. "AA DD", "A D" etc
       where A is address in hex, D is data in hex.
       Multiple address/data pairs may be separated by spaces.
    */
    if (count < 3)
        return 0;

    dd = fp->private_data;

    mbuf = kzalloc(count, GFP_KERNEL);
    if (!mbuf) {
        rc = -ENOMEM;
        goto dbfs_write_exit;
    }

    if (copy_from_user(mbuf, buf, count)) {
        rc = -EFAULT;
        goto dbfs_write_exit_copy;
    }

    p = mbuf;

    while (isspace(*p))
        p++;
    do {
        val = simple_strtoul(p, (char **)&np, 16);
        if ((val > BMA250_LAST_REG) || (p == np)) {
            rc = -EINVAL;
            goto dbfs_write_exit_copy;
        }
        while (isspace(*np) && ((np - mbuf) < count))
            np++;
        p = np;
        reg = (u8)val;

        val = simple_strtoul(p, (char **)&np, 16);
        if ((val > 0xFF)  || (p == np)) {
            rc = -EINVAL;
            goto dbfs_write_exit_copy;
        }
        while (isspace(*np) && ((np - mbuf) < count))
            np++;
        p = np;
        data = (u8)val;

        rc = bma250_ic_write(dd->ic_dev, reg, data);

        /* update here to avoid checking g-range at each interrupt */
        if ((!rc) && (reg == BMA250_RANGE_REG))
            dd->shift = bma250_range2shift(data);

    } while (!rc && (np - mbuf) < count);

    if (rc)
        goto dbfs_write_exit;
    kfree(mbuf);

    return count;

dbfs_write_exit_copy:
    kfree(mbuf);
dbfs_write_exit:
    return rc;
}