예제 #1
0
파일: ad9910.c 프로젝트: 7799/linux
static void ad9910_init(struct ad9910_state *st)
{
	struct spi_transfer xfer;
	int ret;
	u8 cfr[5];

	cfr[0] = CFR1;
	cfr[1] = 0;
	cfr[2] = MANUAL_OSK | INVSIC | DDS_SINEOP;
	cfr[3] = AUTO_OSK | OSKEN | ACLR_PHA | ACLR_DIG | LOAD_LRR;
	cfr[4] = 0;

	mutex_lock(&st->lock);

	xfer.len = 5;
	xfer.tx_buf = 𝔠

	ret = spi_sync_transfer(st->sdev, &xfer, 1);
	if (ret)
		goto error_ret;

	cfr[0] = CFR2;
	cfr[1] = ENA_AMP;
	cfr[2] = READ_FTW | DIGR_ENA | ITER_IOUPD;
	cfr[3] = TX_ENA | PDCLK_INV | PDCLK_ENB;
	cfr[4] = PARA_ENA;

	xfer.len = 5;
	xfer.tx_buf = 𝔠

	ret = spi_sync_transfer(st->sdev, &xfer, 1);
	if (ret)
		goto error_ret;

	cfr[0] = CFR3;
	cfr[1] = PLL_ENA;
	cfr[2] = 0;
	cfr[3] = REFCLK_RST | REFCLK_BYP;
	cfr[4] = 0;

	xfer.len = 5;
	xfer.tx_buf = 𝔠

	ret = spi_sync_transfer(st->sdev, &xfer, 1);
	if (ret)
		goto error_ret;

error_ret:
	mutex_unlock(&st->lock);



}
예제 #2
0
파일: ad9852.c 프로젝트: 7799/linux
static void ad9852_init(struct ad9852_state *st)
{
	struct spi_transfer xfer;
	int ret;
	u8 config[5];

	config[0] = addr_contrl;
	config[1] = COMPPD;
	config[2] = REFMULT2 | BYPPLL | PLLRANG;
	config[3] = IEUPCLK;
	config[4] = OSKEN;

	mutex_lock(&st->lock);

	xfer.len = 5;
	xfer.tx_buf = &config;

	ret = spi_sync_transfer(st->sdev, &xfer, 1);
	if (ret)
		goto error_ret;

error_ret:
	mutex_unlock(&st->lock);



}
예제 #3
0
파일: spi.c 프로젝트: asmalldev/linux
/*
 * st33zp24_spi_send
 * Send byte to the TIS register according to the ST33ZP24 SPI protocol.
 * @param: phy_id, the phy description
 * @param: tpm_register, the tpm tis register where the data should be written
 * @param: tpm_data, the tpm_data to write inside the tpm_register
 * @param: tpm_size, The length of the data
 * @return: should be zero if success else a negative error code.
 */
static int st33zp24_spi_send(void *phy_id, u8 tpm_register, u8 *tpm_data,
			     int tpm_size)
{
	int total_length = 0, ret = 0;
	struct st33zp24_spi_phy *phy = phy_id;
	struct spi_device *dev = phy->spi_device;
	struct spi_transfer spi_xfer = {
		.tx_buf = phy->tx_buf,
		.rx_buf = phy->rx_buf,
	};

	/* Pre-Header */
	phy->tx_buf[total_length++] = TPM_WRITE_DIRECTION | LOCALITY0;
	phy->tx_buf[total_length++] = tpm_register;

	if (tpm_size > 0 && tpm_register == TPM_DATA_FIFO) {
		phy->tx_buf[total_length++] = tpm_size >> 8;
		phy->tx_buf[total_length++] = tpm_size;
	}

	memcpy(&phy->tx_buf[total_length], tpm_data, tpm_size);
	total_length += tpm_size;

	memset(&phy->tx_buf[total_length], TPM_DUMMY_BYTE, phy->latency);

	spi_xfer.len = total_length + phy->latency;

	ret = spi_sync_transfer(dev, &spi_xfer, 1);
	if (ret == 0)
		ret = phy->rx_buf[total_length + phy->latency - 1];

	return st33zp24_status_to_errno(ret);
} /* st33zp24_spi_send() */
예제 #4
0
static ssize_t ad5930_set_parameter(struct device *dev,
					struct device_attribute *attr,
					const char *buf,
					size_t len)
{
	struct spi_transfer xfer;
	int ret;
	struct ad5903_config *config = (struct ad5903_config *)buf;
	struct iio_dev *idev = dev_to_iio_dev(dev);
	struct ad5930_state *st = iio_priv(idev);

	config->control = (config->control & ~value_mask);
	config->incnum = (config->control & ~value_mask) | (1 << addr_shift);
	config->frqdelt[0] = (config->control & ~value_mask) | (2 << addr_shift);
	config->frqdelt[1] = (config->control & ~value_mask) | 3 << addr_shift;
	config->incitvl = (config->control & ~value_mask) | 4 << addr_shift;
	config->buritvl = (config->control & ~value_mask) | 8 << addr_shift;
	config->strtfrq[0] = (config->control & ~value_mask) | 0xc << addr_shift;
	config->strtfrq[1] = (config->control & ~value_mask) | 0xd << addr_shift;

	xfer.len = len;
	xfer.tx_buf = config;
	mutex_lock(&st->lock);

	ret = spi_sync_transfer(st->sdev, &xfer, 1);
	if (ret)
		goto error_ret;
error_ret:
	mutex_unlock(&st->lock);

	return ret ? ret : len;
}
예제 #5
0
파일: rf69.c 프로젝트: val2k/linux
int rf69_read_fifo (struct spi_device *spi, u8 *buffer, unsigned int size)
{
	#ifdef DEBUG_FIFO_ACCESS
		int i;
	#endif
	struct spi_transfer transfer;
	u8 local_buffer[FIFO_SIZE + 1];
	int retval;

	if (size > FIFO_SIZE) {
		#ifdef DEBUG
			dev_dbg(&spi->dev, "read fifo: passed in buffer bigger then internal buffer \n");
		#endif
		return -EMSGSIZE;
	}

	/* prepare a bidirectional transfer */
	local_buffer[0] = REG_FIFO;
	memset(&transfer, 0, sizeof(transfer));
	transfer.tx_buf = local_buffer;
	transfer.rx_buf = local_buffer;
	transfer.len	= size+1;

	retval = spi_sync_transfer(spi, &transfer, 1);

	#ifdef DEBUG_FIFO_ACCESS
		for (i = 0; i < size; i++)
			dev_dbg(&spi->dev, "%d - 0x%x\n", i, local_buffer[i+1]);
	#endif

	memcpy(buffer, &local_buffer[1], size);  // TODO: ohne memcopy wäre schöner

	return retval;
}
예제 #6
0
static int m25p80_read_reg(struct spi_nor *nor, u8 code, u8 *val, int len)
{
	struct m25p *flash = nor->priv;
	struct spi_device *spi = flash->spi;
	unsigned code_nbits, data_nbits;
	struct spi_transfer xfers[2];
	int ret;

	/* Get transfer protocols (addr_nbits is not relevant here). */
	ret = m25p80_proto2nbits(nor->reg_proto,
				 &code_nbits, NULL, &data_nbits);
	if (ret < 0)
		return ret;

	/* Set up transfers. */
	memset(xfers, 0, sizeof(xfers));

	flash->command[0] = code;
	xfers[0].len = 1;
	xfers[0].tx_buf = flash->command;
	xfers[0].tx_nbits = code_nbits;

	xfers[1].len = len;
	xfers[1].rx_buf = &flash->command[1];
	xfers[1].rx_nbits = data_nbits;

	/* Process command. */
	ret = spi_sync_transfer(spi, xfers, 2);
	if (ret < 0)
		dev_err(&spi->dev, "error %d reading %x\n", ret, code);
	else
		memcpy(val, &flash->command[1], len);

	return ret;
}
예제 #7
0
파일: ad9951.c 프로젝트: 7799/linux
static ssize_t ad9951_set_parameter(struct device *dev,
					struct device_attribute *attr,
					const char *buf,
					size_t len)
{
	struct spi_transfer xfer;
	int ret;
	struct ad9951_config *config = (struct ad9951_config *)buf;
	struct iio_dev *idev = dev_to_iio_dev(dev);
	struct ad9951_state *st = iio_priv(idev);

	xfer.len = 3;
	xfer.tx_buf = &config->asf[0];
	mutex_lock(&st->lock);

	ret = spi_sync_transfer(st->sdev, &xfer, 1);
	if (ret)
		goto error_ret;

	xfer.len = 2;
	xfer.tx_buf = &config->arr[0];

	ret = spi_sync_transfer(st->sdev, &xfer, 1);
	if (ret)
		goto error_ret;

	xfer.len = 5;
	xfer.tx_buf = &config->ftw0[0];

	ret = spi_sync_transfer(st->sdev, &xfer, 1);
	if (ret)
		goto error_ret;

	xfer.len = 3;
	xfer.tx_buf = &config->ftw1[0];

	ret = spi_sync_transfer(st->sdev, &xfer, 1);
	if (ret)
		goto error_ret;
error_ret:
	mutex_unlock(&st->lock);

	return ret ? ret : len;
}
예제 #8
0
파일: spi.c 프로젝트: mangOH/mangOH
static int mt7697spi_write_then_read(struct spi_device *spi, const void *txbuf,
                                     void *rxbuf, unsigned len)
{
	struct spi_transfer transfer = {
		.tx_buf	= txbuf,
		.rx_buf	= rxbuf,
		.len	= len,
	};

	return spi_sync_transfer(spi, &transfer, 1);
}
예제 #9
0
파일: ad9951.c 프로젝트: 7799/linux
static void ad9951_init(struct ad9951_state *st)
{
	struct spi_transfer xfer;
	int ret;
	u8 cfr[5];

	cfr[0] = CFR1;
	cfr[1] = 0;
	cfr[2] = LSB_FST | CLR_PHA | SINE_OPT | ACLR_PHA;
	cfr[3] = AUTO_OSK | OSKEN | LOAD_ARR;
	cfr[4] = 0;

	mutex_lock(&st->lock);

	xfer.len = 5;
	xfer.tx_buf = &cfr;

	ret = spi_sync_transfer(st->sdev, &xfer, 1);
	if (ret)
		goto error_ret;

	cfr[0] = CFR2;
	cfr[1] = VCO_RANGE;
	cfr[2] = HSPD_SYNC;
	cfr[3] = 0;

	xfer.len = 4;
	xfer.tx_buf = &cfr;

	ret = spi_sync_transfer(st->sdev, &xfer, 1);
	if (ret)
		goto error_ret;

error_ret:
	mutex_unlock(&st->lock);



}
예제 #10
0
파일: spi.c 프로젝트: asmalldev/linux
/*
 * st33zp24_spi_read8_recv
 * Recv byte from the TIS register according to the ST33ZP24 SPI protocol.
 * @param: phy_id, the phy description
 * @param: tpm_register, the tpm tis register where the data should be read
 * @param: tpm_data, the TPM response
 * @param: tpm_size, tpm TPM response size to read.
 * @return: should be zero if success else a negative error code.
 */
static int st33zp24_spi_read8_reg(void *phy_id, u8 tpm_register, u8 *tpm_data,
				  int tpm_size)
{
	int total_length = 0, ret;
	struct st33zp24_spi_phy *phy = phy_id;
	struct spi_device *dev = phy->spi_device;
	struct spi_transfer spi_xfer = {
		.tx_buf = phy->tx_buf,
		.rx_buf = phy->rx_buf,
	};

	/* Pre-Header */
	phy->tx_buf[total_length++] = LOCALITY0;
	phy->tx_buf[total_length++] = tpm_register;

	memset(&phy->tx_buf[total_length], TPM_DUMMY_BYTE,
	       phy->latency + tpm_size);

	spi_xfer.len = total_length + phy->latency + tpm_size;

	/* header + status byte + size of the data + status byte */
	ret = spi_sync_transfer(dev, &spi_xfer, 1);
	if (tpm_size > 0 && ret == 0) {
		ret = phy->rx_buf[total_length + phy->latency - 1];

		memcpy(tpm_data, phy->rx_buf + total_length + phy->latency,
		       tpm_size);
	}

	return ret;
} /* st33zp24_spi_read8_reg() */

/*
 * st33zp24_spi_recv
 * Recv byte from the TIS register according to the ST33ZP24 SPI protocol.
 * @param: phy_id, the phy description
 * @param: tpm_register, the tpm tis register where the data should be read
 * @param: tpm_data, the TPM response
 * @param: tpm_size, tpm TPM response size to read.
 * @return: number of byte read successfully: should be one if success.
 */
static int st33zp24_spi_recv(void *phy_id, u8 tpm_register, u8 *tpm_data,
			     int tpm_size)
{
	int ret;

	ret = st33zp24_spi_read8_reg(phy_id, tpm_register, tpm_data, tpm_size);
	if (!st33zp24_status_to_errno(ret))
		return tpm_size;
	return ret;
} /* st33zp24_spi_recv() */
예제 #11
0
파일: ir-spi.c 프로젝트: mdamt/linux
static int ir_spi_tx(struct rc_dev *dev,
		     unsigned int *buffer, unsigned int count)
{
	int i;
	int ret;
	unsigned int len = 0;
	struct ir_spi_data *idata = dev->priv;
	struct spi_transfer xfer;

	/* convert the pulse/space signal to raw binary signal */
	for (i = 0; i < count; i++) {
		unsigned int periods;
		int j;
		u16 val;

		periods = DIV_ROUND_CLOSEST(buffer[i] * idata->freq, 1000000);

		if (len + periods >= IR_SPI_MAX_BUFSIZE)
			return -EINVAL;

		/*
		 * the first value in buffer is a pulse, so that 0, 2, 4, ...
		 * contain a pulse duration. On the contrary, 1, 3, 5, ...
		 * contain a space duration.
		 */
		val = (i % 2) ? idata->space : idata->pulse;
		for (j = 0; j < periods; j++)
			idata->tx_buf[len++] = val;
	}

	memset(&xfer, 0, sizeof(xfer));

	xfer.speed_hz = idata->freq * 16;
	xfer.len = len * sizeof(*idata->tx_buf);
	xfer.tx_buf = idata->tx_buf;

	ret = regulator_enable(idata->regulator);
	if (ret)
		return ret;

	ret = spi_sync_transfer(idata->spi, &xfer, 1);
	if (ret)
		dev_err(&idata->spi->dev, "unable to deliver the signal\n");

	regulator_disable(idata->regulator);

	return ret ? ret : count;
}
예제 #12
0
static ssize_t ad9850_set_parameter(struct device *dev,
					struct device_attribute *attr,
					const char *buf,
					size_t len)
{
	struct spi_transfer xfer;
	int ret;
	struct ad9850_config *config = (struct ad9850_config *)buf;
	struct iio_dev *idev = dev_to_iio_dev(dev);
	struct ad9850_state *st = iio_priv(idev);

	xfer.len = len;
	xfer.tx_buf = config;
	mutex_lock(&st->lock);

	ret = spi_sync_transfer(st->sdev, &xfer, 1);
	mutex_unlock(&st->lock);

	return ret ? ret : len;
}
예제 #13
0
파일: ad5504.c 프로젝트: ChineseDr/linux
static int ad5504_spi_read(struct ad5504_state *st, u8 addr)
{
    int ret;
    struct spi_transfer t = {
        .tx_buf = &st->data[0],
        .rx_buf = &st->data[1],
        .len = 2,
    };

    st->data[0] = cpu_to_be16(AD5504_CMD_READ | AD5504_ADDR(addr));
    ret = spi_sync_transfer(st->spi, &t, 1);
    if (ret < 0)
        return ret;

    return be16_to_cpu(st->data[1]) & AD5504_RES_MASK;
}

static int ad5504_read_raw(struct iio_dev *indio_dev,
                           struct iio_chan_spec const *chan,
                           int *val,
                           int *val2,
                           long m)
{
    struct ad5504_state *st = iio_priv(indio_dev);
    int ret;

    switch (m) {
    case IIO_CHAN_INFO_RAW:
        ret = ad5504_spi_read(st, chan->address);
        if (ret < 0)
            return ret;

        *val = ret;

        return IIO_VAL_INT;
    case IIO_CHAN_INFO_SCALE:
        *val = st->vref_mv;
        *val2 = chan->scan_type.realbits;
        return IIO_VAL_FRACTIONAL_LOG2;
    }
    return -EINVAL;
}

static int ad5504_write_raw(struct iio_dev *indio_dev,
                            struct iio_chan_spec const *chan,
                            int val,
                            int val2,
                            long mask)
{
    struct ad5504_state *st = iio_priv(indio_dev);

    switch (mask) {
    case IIO_CHAN_INFO_RAW:
        if (val >= (1 << chan->scan_type.realbits) || val < 0)
            return -EINVAL;

        return ad5504_spi_write(st, chan->address, val);
    default:
        return -EINVAL;
    }
}

static const char * const ad5504_powerdown_modes[] = {
    "20kohm_to_gnd",
    "three_state",
};

static int ad5504_get_powerdown_mode(struct iio_dev *indio_dev,
                                     const struct iio_chan_spec *chan)
{
    struct ad5504_state *st = iio_priv(indio_dev);

    return st->pwr_down_mode;
}

static int ad5504_set_powerdown_mode(struct iio_dev *indio_dev,
                                     const struct iio_chan_spec *chan, unsigned int mode)
{
    struct ad5504_state *st = iio_priv(indio_dev);

    st->pwr_down_mode = mode;

    return 0;
}

static const struct iio_enum ad5504_powerdown_mode_enum = {
    .items = ad5504_powerdown_modes,
    .num_items = ARRAY_SIZE(ad5504_powerdown_modes),
    .get = ad5504_get_powerdown_mode,
    .set = ad5504_set_powerdown_mode,
};

static ssize_t ad5504_read_dac_powerdown(struct iio_dev *indio_dev,
        uintptr_t private, const struct iio_chan_spec *chan, char *buf)
{
    struct ad5504_state *st = iio_priv(indio_dev);

    return sprintf(buf, "%d\n",
                   !(st->pwr_down_mask & (1 << chan->channel)));
}

static ssize_t ad5504_write_dac_powerdown(struct iio_dev *indio_dev,
        uintptr_t private, const struct iio_chan_spec *chan, const char *buf,
        size_t len)
{
    bool pwr_down;
    int ret;
    struct ad5504_state *st = iio_priv(indio_dev);

    ret = strtobool(buf, &pwr_down);
    if (ret)
        return ret;

    if (pwr_down)
        st->pwr_down_mask |= (1 << chan->channel);
    else
        st->pwr_down_mask &= ~(1 << chan->channel);

    ret = ad5504_spi_write(st, AD5504_ADDR_CTRL,
                           AD5504_DAC_PWRDWN_MODE(st->pwr_down_mode) |
                           AD5504_DAC_PWR(st->pwr_down_mask));

    /* writes to the CTRL register must be followed by a NOOP */
    ad5504_spi_write(st, AD5504_ADDR_NOOP, 0);

    return ret ? ret : len;
}

static IIO_CONST_ATTR(temp0_thresh_rising_value, "110000");
static IIO_CONST_ATTR(temp0_thresh_rising_en, "1");

static struct attribute *ad5504_ev_attributes[] = {
    &iio_const_attr_temp0_thresh_rising_value.dev_attr.attr,
    &iio_const_attr_temp0_thresh_rising_en.dev_attr.attr,
    NULL,
};

static struct attribute_group ad5504_ev_attribute_group = {
    .attrs = ad5504_ev_attributes,
};

static irqreturn_t ad5504_event_handler(int irq, void *private)
{
    iio_push_event(private,
                   IIO_UNMOD_EVENT_CODE(IIO_TEMP,
                                        0,
                                        IIO_EV_TYPE_THRESH,
                                        IIO_EV_DIR_RISING),
                   iio_get_time_ns((struct iio_dev *)private));

    return IRQ_HANDLED;
}
예제 #14
0
파일: spi.c 프로젝트: Chong-Li/cse522
/*
 * Writing a frame must not return the number of written bytes.
 * It must return either zero for success, or <0 for error.
 * In addition, it must not alter the skb
 */
static int st_nci_spi_write(void *phy_id, struct sk_buff *skb)
{
	int r;
	struct st_nci_spi_phy *phy = phy_id;
	struct spi_device *dev = phy->spi_dev;
	struct sk_buff *skb_rx;
	u8 buf[ST_NCI_SPI_MAX_SIZE + NCI_DATA_HDR_SIZE +
	       ST_NCI_FRAME_HEADROOM + ST_NCI_FRAME_TAILROOM];
	struct spi_transfer spi_xfer = {
		.tx_buf = skb->data,
		.rx_buf = buf,
		.len = skb->len,
	};

	if (phy->ndlc->hard_fault != 0)
		return phy->ndlc->hard_fault;

	r = spi_sync_transfer(dev, &spi_xfer, 1);
	/*
	 * We may have received some valuable data on miso line.
	 * Send them back in the ndlc state machine.
	 */
	if (!r) {
		skb_rx = alloc_skb(skb->len, GFP_KERNEL);
		if (!skb_rx) {
			r = -ENOMEM;
			goto exit;
		}

		skb_put(skb_rx, skb->len);
		memcpy(skb_rx->data, buf, skb->len);
		ndlc_recv(phy->ndlc, skb_rx);
	}

exit:
	return r;
}

/*
 * Reads an ndlc frame and returns it in a newly allocated sk_buff.
 * returns:
 * 0 : if received frame is complete
 * -EREMOTEIO : i2c read error (fatal)
 * -EBADMSG : frame was incorrect and discarded
 * -ENOMEM : cannot allocate skb, frame dropped
 */
static int st_nci_spi_read(struct st_nci_spi_phy *phy,
			struct sk_buff **skb)
{
	int r;
	u8 len;
	u8 buf[ST_NCI_SPI_MAX_SIZE];
	struct spi_device *dev = phy->spi_dev;
	struct spi_transfer spi_xfer = {
		.rx_buf = buf,
		.len = ST_NCI_SPI_MIN_SIZE,
	};

	r = spi_sync_transfer(dev, &spi_xfer, 1);
	if (r < 0)
		return -EREMOTEIO;

	len = be16_to_cpu(*(__be16 *) (buf + 2));
	if (len > ST_NCI_SPI_MAX_SIZE) {
		nfc_err(&dev->dev, "invalid frame len\n");
		phy->ndlc->hard_fault = 1;
		return -EBADMSG;
	}

	*skb = alloc_skb(ST_NCI_SPI_MIN_SIZE + len, GFP_KERNEL);
	if (*skb == NULL)
		return -ENOMEM;

	skb_reserve(*skb, ST_NCI_SPI_MIN_SIZE);
	skb_put(*skb, ST_NCI_SPI_MIN_SIZE);
	memcpy((*skb)->data, buf, ST_NCI_SPI_MIN_SIZE);

	if (!len)
		return 0;

	spi_xfer.len = len;
	r = spi_sync_transfer(dev, &spi_xfer, 1);
	if (r < 0) {
		kfree_skb(*skb);
		return -EREMOTEIO;
	}

	skb_put(*skb, len);
	memcpy((*skb)->data + ST_NCI_SPI_MIN_SIZE, buf, len);

	return 0;
}
예제 #15
0
static int ade7854_spi_write_reg_8(struct device *dev,
		u16 reg_address,
		u8 value)
{
	int ret;
	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
	struct ade7854_state *st = iio_priv(indio_dev);
	struct spi_transfer xfer = {
		.tx_buf = st->tx,
		.bits_per_word = 8,
		.len = 4,
	};

	mutex_lock(&st->buf_lock);
	st->tx[0] = ADE7854_WRITE_REG;
	st->tx[1] = (reg_address >> 8) & 0xFF;
	st->tx[2] = reg_address & 0xFF;
	st->tx[3] = value & 0xFF;

	ret = spi_sync_transfer(st->spi, &xfer, 1);
	mutex_unlock(&st->buf_lock);

	return ret;
}

static int ade7854_spi_write_reg_16(struct device *dev,
		u16 reg_address,
		u16 value)
{
	int ret;
	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
	struct ade7854_state *st = iio_priv(indio_dev);
	struct spi_transfer xfer = {
		.tx_buf = st->tx,
		.bits_per_word = 8,
		.len = 5,
	};

	mutex_lock(&st->buf_lock);
	st->tx[0] = ADE7854_WRITE_REG;
	st->tx[1] = (reg_address >> 8) & 0xFF;
	st->tx[2] = reg_address & 0xFF;
	st->tx[3] = (value >> 8) & 0xFF;
	st->tx[4] = value & 0xFF;

	ret = spi_sync_transfer(st->spi, &xfer, 1);
	mutex_unlock(&st->buf_lock);

	return ret;
}

static int ade7854_spi_write_reg_24(struct device *dev,
		u16 reg_address,
		u32 value)
{
	int ret;
	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
	struct ade7854_state *st = iio_priv(indio_dev);
	struct spi_transfer xfer = {
		.tx_buf = st->tx,
		.bits_per_word = 8,
		.len = 6,
	};

	mutex_lock(&st->buf_lock);
	st->tx[0] = ADE7854_WRITE_REG;
	st->tx[1] = (reg_address >> 8) & 0xFF;
	st->tx[2] = reg_address & 0xFF;
	st->tx[3] = (value >> 16) & 0xFF;
	st->tx[4] = (value >> 8) & 0xFF;
	st->tx[5] = value & 0xFF;

	ret = spi_sync_transfer(st->spi, &xfer, 1);
	mutex_unlock(&st->buf_lock);

	return ret;
}

static int ade7854_spi_write_reg_32(struct device *dev,
		u16 reg_address,
		u32 value)
{
	int ret;
	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
	struct ade7854_state *st = iio_priv(indio_dev);
	struct spi_transfer xfer = {
		.tx_buf = st->tx,
		.bits_per_word = 8,
		.len = 7,
	};

	mutex_lock(&st->buf_lock);
	st->tx[0] = ADE7854_WRITE_REG;
	st->tx[1] = (reg_address >> 8) & 0xFF;
	st->tx[2] = reg_address & 0xFF;
	st->tx[3] = (value >> 24) & 0xFF;
	st->tx[4] = (value >> 16) & 0xFF;
	st->tx[5] = (value >> 8) & 0xFF;
	st->tx[6] = value & 0xFF;

	ret = spi_sync_transfer(st->spi, &xfer, 1);
	mutex_unlock(&st->buf_lock);

	return ret;
}

static int ade7854_spi_read_reg_8(struct device *dev,
		u16 reg_address,
		u8 *val)
{
	struct iio_dev *indio_dev = dev_to_iio_dev(dev);
	struct ade7854_state *st = iio_priv(indio_dev);
	int ret;
	struct spi_transfer xfers[] = {
		{
			.tx_buf = st->tx,
			.bits_per_word = 8,
			.len = 3,
		}, {
			.rx_buf = st->rx,
			.bits_per_word = 8,
			.len = 1,
		}
	};
예제 #16
0
파일: adis16130.c 프로젝트: 020gzh/linux
static int adis16130_spi_read(struct iio_dev *indio_dev, u8 reg_addr, u32 *val)
{
	int ret;
	struct adis16130_state *st = iio_priv(indio_dev);
	struct spi_transfer xfer = {
		.tx_buf = st->buf,
		.rx_buf = st->buf,
		.len = 4,
	};

	mutex_lock(&st->buf_lock);

	st->buf[0] = ADIS16130_CON_RD | reg_addr;
	st->buf[1] = st->buf[2] = st->buf[3] = 0;

	ret = spi_sync_transfer(st->us, &xfer, 1);
	if (ret == 0)
		*val = (st->buf[1] << 16) | (st->buf[2] << 8) | st->buf[3];
	mutex_unlock(&st->buf_lock);

	return ret;
}

static int adis16130_read_raw(struct iio_dev *indio_dev,
			      struct iio_chan_spec const *chan,
			      int *val, int *val2,
			      long mask)
{
	int ret;
	u32 temp;

	switch (mask) {
	case IIO_CHAN_INFO_RAW:
		/* Take the iio_dev status lock */
		mutex_lock(&indio_dev->mlock);
		ret = adis16130_spi_read(indio_dev, chan->address, &temp);
		mutex_unlock(&indio_dev->mlock);
		if (ret)
			return ret;
		*val = temp;
		return IIO_VAL_INT;
	case IIO_CHAN_INFO_SCALE:
		switch (chan->type) {
		case IIO_ANGL_VEL:
			/* 0 degree = 838860, 250 degree = 14260608 */
			*val = 250;
			*val2 = 336440817; /* RAD_TO_DEGREE(14260608 - 8388608) */
			return IIO_VAL_FRACTIONAL;
		case IIO_TEMP:
			/* 0C = 8036283, 105C = 9516048 */
			*val = 105000;
			*val2 = 9516048 - 8036283;
			return IIO_VAL_FRACTIONAL;
		default:
			return -EINVAL;
		}
	case IIO_CHAN_INFO_OFFSET:
		switch (chan->type) {
		case IIO_ANGL_VEL:
			*val = -8388608;
			return IIO_VAL_INT;
		case IIO_TEMP:
			*val = -8036283;
			return IIO_VAL_INT;
		default:
			return -EINVAL;
		}
	}

	return -EINVAL;
}
예제 #17
0
파일: ade7754.c 프로젝트: 7799/linux
	struct spi_transfer xfers[] = {
		{
			.tx_buf = st->tx,
			.rx_buf = st->rx,
			.bits_per_word = 8,
			.len = 4,
		},
	};

	mutex_lock(&st->buf_lock);
	st->tx[0] = ADE7754_READ_REG(reg_address);
	st->tx[1] = 0;
	st->tx[2] = 0;
	st->tx[3] = 0;

	ret = spi_sync_transfer(st->us, xfers, ARRAY_SIZE(xfers));
	if (ret) {
		dev_err(&st->us->dev, "problem when reading 24 bit register 0x%02X",
				reg_address);
		goto error_ret;
	}
	*val = (st->rx[1] << 16) | (st->rx[2] << 8) | st->rx[3];

error_ret:
	mutex_unlock(&st->buf_lock);
	return ret;
}

static ssize_t ade7754_read_8bit(struct device *dev,
		struct device_attribute *attr,
		char *buf)
예제 #18
0
파일: ad9523.c 프로젝트: 03199618/linux
	struct spi_transfer t[] = {
		{
			.tx_buf = &st->data[0].d8[2],
			.len = 2,
		}, {
			.rx_buf = &st->data[1].d8[4 - AD9523_TRANSF_LEN(addr)],
			.len = AD9523_TRANSF_LEN(addr),
		},
	};

	st->data[0].d32 = cpu_to_be32(AD9523_READ |
				      AD9523_CNT(AD9523_TRANSF_LEN(addr)) |
				      AD9523_ADDR(addr));

	ret = spi_sync_transfer(st->spi, t, ARRAY_SIZE(t));
	if (ret < 0)
		dev_err(&indio_dev->dev, "read failed (%d)", ret);
	else
		ret = be32_to_cpu(st->data[1].d32) & (0xFFFFFF >>
				  (8 * (3 - AD9523_TRANSF_LEN(addr))));

	return ret;
};

static int ad9523_write(struct iio_dev *indio_dev, unsigned addr, unsigned val)
{
	struct ad9523_state *st = iio_priv(indio_dev);
	int ret;
	struct spi_transfer t[] = {
		{
예제 #19
0
파일: ad9852.c 프로젝트: 7799/linux
static ssize_t ad9852_set_parameter(struct device *dev,
					struct device_attribute *attr,
					const char *buf,
					size_t len)
{
	struct spi_transfer xfer;
	int ret;
	struct ad9852_config *config = (struct ad9852_config *)buf;
	struct iio_dev *idev = dev_to_iio_dev(dev);
	struct ad9852_state *st = iio_priv(idev);

	xfer.len = 3;
	xfer.tx_buf = &config->phajst0[0];
	mutex_lock(&st->lock);

	ret = spi_sync_transfer(st->sdev, &xfer, 1);
	if (ret)
		goto error_ret;

	xfer.len = 3;
	xfer.tx_buf = &config->phajst1[0];

	ret = spi_sync_transfer(st->sdev, &xfer, 1);
	if (ret)
		goto error_ret;

	xfer.len = 6;
	xfer.tx_buf = &config->fretun1[0];

	ret = spi_sync_transfer(st->sdev, &xfer, 1);
	if (ret)
		goto error_ret;

	xfer.len = 6;
	xfer.tx_buf = &config->fretun2[0];

	ret = spi_sync_transfer(st->sdev, &xfer, 1);
	if (ret)
		goto error_ret;

	xfer.len = 6;
	xfer.tx_buf = &config->dltafre[0];

	ret = spi_sync_transfer(st->sdev, &xfer, 1);
	if (ret)
		goto error_ret;

	xfer.len = 5;
	xfer.tx_buf = &config->updtclk[0];

	ret = spi_sync_transfer(st->sdev, &xfer, 1);
	if (ret)
		goto error_ret;

	xfer.len = 4;
	xfer.tx_buf = &config->ramprat[0];

	ret = spi_sync_transfer(st->sdev, &xfer, 1);
	if (ret)
		goto error_ret;

	xfer.len = 5;
	xfer.tx_buf = &config->control[0];

	ret = spi_sync_transfer(st->sdev, &xfer, 1);
	if (ret)
		goto error_ret;

	xfer.len = 3;
	xfer.tx_buf = &config->outpskm[0];

	ret = spi_sync_transfer(st->sdev, &xfer, 1);
	if (ret)
		goto error_ret;

	xfer.len = 2;
	xfer.tx_buf = &config->outpskr[0];

	ret = spi_sync_transfer(st->sdev, &xfer, 1);
	if (ret)
		goto error_ret;

	xfer.len = 3;
	xfer.tx_buf = &config->daccntl[0];

	ret = spi_sync_transfer(st->sdev, &xfer, 1);
	if (ret)
		goto error_ret;
error_ret:
	mutex_unlock(&st->lock);

	return ret ? ret : len;
}
예제 #20
0
파일: ad9910.c 프로젝트: 7799/linux
static ssize_t ad9910_set_parameter(struct device *dev,
					struct device_attribute *attr,
					const char *buf,
					size_t len)
{
	struct spi_transfer xfer;
	int ret;
	struct ad9910_config *config = (struct ad9910_config *)buf;
	struct iio_dev *idev = dev_to_iio_dev(dev);
	struct ad9910_state *st = iio_priv(idev);

	xfer.len = 5;
	xfer.tx_buf = &config->auxdac[0];
	mutex_lock(&st->lock);

	ret = spi_sync_transfer(st->sdev, &xfer, 1);
	if (ret)
		goto error_ret;

	xfer.len = 5;
	xfer.tx_buf = &config->ioupd[0];

	ret = spi_sync_transfer(st->sdev, &xfer, 1);
	if (ret)
		goto error_ret;

	xfer.len = 5;
	xfer.tx_buf = &config->ftw[0];

	ret = spi_sync_transfer(st->sdev, &xfer, 1);
	if (ret)
		goto error_ret;

	xfer.len = 3;
	xfer.tx_buf = &config->pow[0];

	ret = spi_sync_transfer(st->sdev, &xfer, 1);
	if (ret)
		goto error_ret;

	xfer.len = 5;
	xfer.tx_buf = &config->asf[0];

	ret = spi_sync_transfer(st->sdev, &xfer, 1);
	if (ret)
		goto error_ret;

	xfer.len = 5;
	xfer.tx_buf = &config->multc[0];

	ret = spi_sync_transfer(st->sdev, &xfer, 1);
	if (ret)
		goto error_ret;

	xfer.len = 9;
	xfer.tx_buf = &config->dig_rampl[0];

	ret = spi_sync_transfer(st->sdev, &xfer, 1);
	if (ret)
		goto error_ret;

	xfer.len = 9;
	xfer.tx_buf = &config->dig_ramps[0];

	ret = spi_sync_transfer(st->sdev, &xfer, 1);
	if (ret)
		goto error_ret;

	xfer.len = 5;
	xfer.tx_buf = &config->dig_rampr[0];

	ret = spi_sync_transfer(st->sdev, &xfer, 1);
	if (ret)
		goto error_ret;

	xfer.len = 9;
	xfer.tx_buf = &config->sin_tonep0[0];

	ret = spi_sync_transfer(st->sdev, &xfer, 1);
	if (ret)
		goto error_ret;

	xfer.len = 9;
	xfer.tx_buf = &config->sin_tonep1[0];

	ret = spi_sync_transfer(st->sdev, &xfer, 1);
	if (ret)
		goto error_ret;

	xfer.len = 9;
	xfer.tx_buf = &config->sin_tonep2[0];

	ret = spi_sync_transfer(st->sdev, &xfer, 1);
	if (ret)
		goto error_ret;
	xfer.len = 9;
	xfer.tx_buf = &config->sin_tonep3[0];

	ret = spi_sync_transfer(st->sdev, &xfer, 1);
	if (ret)
		goto error_ret;

	xfer.len = 9;
	xfer.tx_buf = &config->sin_tonep4[0];

	ret = spi_sync_transfer(st->sdev, &xfer, 1);
	if (ret)
		goto error_ret;

	xfer.len = 9;
	xfer.tx_buf = &config->sin_tonep5[0];

	ret = spi_sync_transfer(st->sdev, &xfer, 1);
	if (ret)
		goto error_ret;

	xfer.len = 9;
	xfer.tx_buf = &config->sin_tonep6[0];

	ret = spi_sync_transfer(st->sdev, &xfer, 1);
	if (ret)
		goto error_ret;

	xfer.len = 9;
	xfer.tx_buf = &config->sin_tonep7[0];

	ret = spi_sync_transfer(st->sdev, &xfer, 1);
	if (ret)
		goto error_ret;
error_ret:
	mutex_unlock(&st->lock);

	return ret ? ret : len;
}