Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 6d3a6379 authored by Greg Kroah-Hartman's avatar Greg Kroah-Hartman
Browse files

Merge tag 'iio-for-3.10c' of...

Merge tag 'iio-for-3.10c' of git://git.kernel.org/pub/scm/linux/kernel/git/jic23/iio into staging-next

Jonathan writes:
	Third round of IIO cleanups, graduations and new stuff for the 3.10 cycle.

	A small set including 3 things.
	1) A short cleanup series for the ak8975.
	2) Graduation of ak8975 out of staging.
	3) Some additional bits for the at91 adc driver to cover low resolution
	   modes, sleep and a little bit of missing documentation.
parents 03b7f67b beca9e76
Loading
Loading
Loading
Loading
+13 −0
Original line number Diff line number Diff line
@@ -14,9 +14,19 @@ Required properties:
  - atmel,adc-status-register: Offset of the Interrupt Status Register
  - atmel,adc-trigger-register: Offset of the Trigger Register
  - atmel,adc-vref: Reference voltage in millivolts for the conversions
  - atmel,adc-res: List of resolution in bits supported by the ADC. List size
		   must be two at least.
  - atmel,adc-res-names: Contains one identifier string for each resolution
			 in atmel,adc-res property. "lowres" and "highres"
			 identifiers are required.

Optional properties:
  - atmel,adc-use-external: Boolean to enable of external triggers
  - atmel,adc-use-res: String corresponding to an identifier from
		       atmel,adc-res-names property. If not specified, the highest
		       resolution will be used.
  - atmel,adc-sleep-mode: Boolean to enable sleep mode when no conversion
  - atmel,adc-sample-hold-time: Sample and Hold Time in microseconds
 
Optional trigger Nodes:
  - Required properties:
@@ -40,6 +50,9 @@ adc0: adc@fffb0000 {
	atmel,adc-trigger-register = <0x08>;
	atmel,adc-use-external;
	atmel,adc-vref = <3300>;
	atmel,adc-res = <8 10>;
	atmel,adc-res-names = "lowres", "highres";
	atmel,adc-use-res = "lowres";

	trigger@0 {
		trigger-name = "external-rising";
+85 −5
Original line number Diff line number Diff line
@@ -52,11 +52,15 @@ struct at91_adc_state {
	void __iomem		*reg_base;
	struct at91_adc_reg_desc *registers;
	u8			startup_time;
	u8			sample_hold_time;
	bool			sleep_mode;
	struct iio_trigger	**trig;
	struct at91_adc_trigger	*trigger_list;
	u32			trigger_number;
	bool			use_external;
	u32			vref_mv;
	u32			res;		/* resolution used for convertions */
	bool			low_res;	/* the resolution corresponds to the lowest one */
	wait_queue_head_t	wq_data_avail;
};

@@ -138,7 +142,7 @@ static int at91_adc_channel_init(struct iio_dev *idev)
		chan->channel = bit;
		chan->scan_index = idx;
		chan->scan_type.sign = 'u';
		chan->scan_type.realbits = 10;
		chan->scan_type.realbits = st->res;
		chan->scan_type.storagebits = 16;
		chan->info_mask_shared_by_type = BIT(IIO_CHAN_INFO_SCALE);
		chan->info_mask_separate = BIT(IIO_CHAN_INFO_RAW);
@@ -372,6 +376,59 @@ static int at91_adc_read_raw(struct iio_dev *idev,
	return -EINVAL;
}

static int at91_adc_of_get_resolution(struct at91_adc_state *st,
				      struct platform_device *pdev)
{
	struct iio_dev *idev = iio_priv_to_dev(st);
	struct device_node *np = pdev->dev.of_node;
	int count, i, ret = 0;
	char *res_name, *s;
	u32 *resolutions;

	count = of_property_count_strings(np, "atmel,adc-res-names");
	if (count < 2) {
		dev_err(&idev->dev, "You must specified at least two resolution names for "
				    "adc-res-names property in the DT\n");
		return count;
	}

	resolutions = kmalloc(count * sizeof(*resolutions), GFP_KERNEL);
	if (!resolutions)
		return -ENOMEM;

	if (of_property_read_u32_array(np, "atmel,adc-res", resolutions, count)) {
		dev_err(&idev->dev, "Missing adc-res property in the DT.\n");
		ret = -ENODEV;
		goto ret;
	}

	if (of_property_read_string(np, "atmel,adc-use-res", (const char **)&res_name))
		res_name = "highres";

	for (i = 0; i < count; i++) {
		if (of_property_read_string_index(np, "atmel,adc-res-names", i, (const char **)&s))
			continue;

		if (strcmp(res_name, s))
			continue;

		st->res = resolutions[i];
		if (!strcmp(res_name, "lowres"))
			st->low_res = true;
		else
			st->low_res = false;

		dev_info(&idev->dev, "Resolution used: %u bits\n", st->res);
		goto ret;
	}

	dev_err(&idev->dev, "There is no resolution for %s\n", res_name);

ret:
	kfree(resolutions);
	return ret;
}

static int at91_adc_probe_dt(struct at91_adc_state *st,
			     struct platform_device *pdev)
{
@@ -400,6 +457,8 @@ static int at91_adc_probe_dt(struct at91_adc_state *st,
	}
	st->num_channels = prop;

	st->sleep_mode = of_property_read_bool(node, "atmel,adc-sleep-mode");

	if (of_property_read_u32(node, "atmel,adc-startup-time", &prop)) {
		dev_err(&idev->dev, "Missing adc-startup-time property in the DT.\n");
		ret = -EINVAL;
@@ -407,6 +466,9 @@ static int at91_adc_probe_dt(struct at91_adc_state *st,
	}
	st->startup_time = prop;

	prop = 0;
	of_property_read_u32(node, "atmel,adc-sample-hold-time", &prop);
	st->sample_hold_time = prop;

	if (of_property_read_u32(node, "atmel,adc-vref", &prop)) {
		dev_err(&idev->dev, "Missing adc-vref property in the DT.\n");
@@ -415,6 +477,10 @@ static int at91_adc_probe_dt(struct at91_adc_state *st,
	}
	st->vref_mv = prop;

	ret = at91_adc_of_get_resolution(st, pdev);
	if (ret)
		goto error_ret;

	st->registers = devm_kzalloc(&idev->dev,
				     sizeof(struct at91_adc_reg_desc),
				     GFP_KERNEL);
@@ -516,11 +582,12 @@ static const struct iio_info at91_adc_info = {

static int at91_adc_probe(struct platform_device *pdev)
{
	unsigned int prsc, mstrclk, ticks, adc_clk;
	unsigned int prsc, mstrclk, ticks, adc_clk, shtim;
	int ret;
	struct iio_dev *idev;
	struct at91_adc_state *st;
	struct resource *res;
	u32 reg;

	idev = iio_device_alloc(sizeof(struct at91_adc_state));
	if (idev == NULL) {
@@ -628,9 +695,22 @@ static int at91_adc_probe(struct platform_device *pdev)
	 */
	ticks = round_up((st->startup_time * adc_clk /
			  1000000) - 1, 8) / 8;
	at91_adc_writel(st, AT91_ADC_MR,
			(AT91_ADC_PRESCAL_(prsc) & AT91_ADC_PRESCAL) |
			(AT91_ADC_STARTUP_(ticks) & AT91_ADC_STARTUP));
	/*
	 * a minimal Sample and Hold Time is necessary for the ADC to guarantee
	 * the best converted final value between two channels selection
	 * The formula thus is : Sample and Hold Time = (shtim + 1) / ADCClock
	 */
	shtim = round_up((st->sample_hold_time * adc_clk /
			  1000000) - 1, 1);

	reg = AT91_ADC_PRESCAL_(prsc) & AT91_ADC_PRESCAL;
	reg |= AT91_ADC_STARTUP_(ticks) & AT91_ADC_STARTUP;
	if (st->low_res)
		reg |= AT91_ADC_LOWRES;
	if (st->sleep_mode)
		reg |= AT91_ADC_SLEEP;
	reg |= AT91_ADC_SHTIM_(shtim) & AT91_ADC_SHTIM;
	at91_adc_writel(st, AT91_ADC_MR, reg);

	/* Setup the ADC channels available on the board */
	ret = at91_adc_channel_init(idev);
+11 −0
Original line number Diff line number Diff line
@@ -3,6 +3,17 @@
#
menu "Magnetometer sensors"

config AK8975
	tristate "Asahi Kasei AK8975 3-Axis Magnetometer"
	depends on I2C
	depends on GPIOLIB
	help
	  Say yes here to build support for Asahi Kasei AK8975 3-Axis
	  Magnetometer.

	  To compile this driver as a module, choose M here: the module
	  will be called ak8975.

config HID_SENSOR_MAGNETOMETER_3D
	depends on HID_SENSOR_HUB
	select IIO_BUFFER
+1 −0
Original line number Diff line number Diff line
@@ -2,6 +2,7 @@
# Makefile for industrial I/O Magnetometer sensor drivers
#

obj-$(CONFIG_AK8975)	+= ak8975.o
obj-$(CONFIG_HID_SENSOR_MAGNETOMETER_3D) += hid-sensor-magn-3d.o

obj-$(CONFIG_IIO_ST_MAGN_3AXIS) += st_magn.o
+17 −52
Original line number Diff line number Diff line
@@ -94,7 +94,6 @@ struct ak8975_data {
	long			raw_to_gauss[3];
	u8			reg_cache[AK8975_MAX_REGS];
	int			eoc_gpio;
	int			eoc_irq;
};

static const int ak8975_index_to_reg[] = {
@@ -123,36 +122,6 @@ static int ak8975_write_data(struct i2c_client *client,
	return 0;
}

/*
 * Helper function to read a contiguous set of the I2C device's registers.
 */
static int ak8975_read_data(struct i2c_client *client,
			    u8 reg, u8 length, u8 *buffer)
{
	int ret;
	struct i2c_msg msg[2] = {
		{
			.addr = client->addr,
			.flags = I2C_M_NOSTART,
			.len = 1,
			.buf = &reg,
		}, {
			.addr = client->addr,
			.flags = I2C_M_RD,
			.len = length,
			.buf = buffer,
		}
	};

	ret = i2c_transfer(client->adapter, msg, 2);
	if (ret < 0) {
		dev_err(&client->dev, "Read from device fails\n");
		return ret;
	}

	return 0;
}

/*
 * Perform some start-of-day setup, including reading the asa calibration
 * values and caching them.
@@ -165,11 +134,12 @@ static int ak8975_setup(struct i2c_client *client)
	int ret;

	/* Confirm that the device we're talking to is really an AK8975. */
	ret = ak8975_read_data(client, AK8975_REG_WIA, 1, &device_id);
	ret = i2c_smbus_read_byte_data(client, AK8975_REG_WIA);
	if (ret < 0) {
		dev_err(&client->dev, "Error reading WIA\n");
		return ret;
	}
	device_id = ret;
	if (device_id != AK8975_DEVICE_ID) {
		dev_err(&client->dev, "Device ak8975 not found\n");
		return -ENODEV;
@@ -187,7 +157,8 @@ static int ak8975_setup(struct i2c_client *client)
	}

	/* Get asa data and store in the device data. */
	ret = ak8975_read_data(client, AK8975_REG_ASAX, 3, data->asa);
	ret = i2c_smbus_read_i2c_block_data(client, AK8975_REG_ASAX,
					    3, data->asa);
	if (ret < 0) {
		dev_err(&client->dev, "Not able to read asa data\n");
		return ret;
@@ -249,7 +220,6 @@ static int ak8975_setup(struct i2c_client *client)
static int wait_conversion_complete_gpio(struct ak8975_data *data)
{
	struct i2c_client *client = data->client;
	u8 read_status;
	u32 timeout_ms = AK8975_MAX_CONVERSION_TIMEOUT;
	int ret;

@@ -265,13 +235,12 @@ static int wait_conversion_complete_gpio(struct ak8975_data *data)
		return -EINVAL;
	}

	ret = ak8975_read_data(client, AK8975_REG_ST1, 1, &read_status);
	if (ret < 0) {
	ret = i2c_smbus_read_byte_data(client, AK8975_REG_ST1);
	if (ret < 0)
		dev_err(&client->dev, "Error in reading ST1\n");

	return ret;
}
	return read_status;
}

static int wait_conversion_complete_polled(struct ak8975_data *data)
{
@@ -283,11 +252,12 @@ static int wait_conversion_complete_polled(struct ak8975_data *data)
	/* Wait for the conversion to complete. */
	while (timeout_ms) {
		msleep(AK8975_CONVERSION_DONE_POLL_TIME);
		ret = ak8975_read_data(client, AK8975_REG_ST1, 1, &read_status);
		ret = i2c_smbus_read_byte_data(client, AK8975_REG_ST1);
		if (ret < 0) {
			dev_err(&client->dev, "Error in reading ST1\n");
			return ret;
		}
		read_status = ret;
		if (read_status)
			break;
		timeout_ms -= AK8975_CONVERSION_DONE_POLL_TIME;
@@ -308,7 +278,6 @@ static int ak8975_read_axis(struct iio_dev *indio_dev, int index, int *val)
	struct i2c_client *client = data->client;
	u16 meas_reg;
	s16 raw;
	u8 read_status;
	int ret;

	mutex_lock(&data->lock);
@@ -332,18 +301,15 @@ static int ak8975_read_axis(struct iio_dev *indio_dev, int index, int *val)
	if (ret < 0)
		goto exit;

	read_status = ret;

	if (read_status & AK8975_REG_ST1_DRDY_MASK) {
		ret = ak8975_read_data(client, AK8975_REG_ST2, 1, &read_status);
	if (ret & AK8975_REG_ST1_DRDY_MASK) {
		ret = i2c_smbus_read_byte_data(client, AK8975_REG_ST2);
		if (ret < 0) {
			dev_err(&client->dev, "Error in reading ST2\n");
			goto exit;
		}
		if (read_status & (AK8975_REG_ST2_DERR_MASK |
		if (ret & (AK8975_REG_ST2_DERR_MASK |
			   AK8975_REG_ST2_HOFL_MASK)) {
			dev_err(&client->dev, "ST2 status error 0x%x\n",
				read_status);
			dev_err(&client->dev, "ST2 status error 0x%x\n", ret);
			ret = -EINVAL;
			goto exit;
		}
@@ -351,12 +317,12 @@ static int ak8975_read_axis(struct iio_dev *indio_dev, int index, int *val)

	/* Read the flux value from the appropriate register
	   (the register is specified in the iio device attributes). */
	ret = ak8975_read_data(client, ak8975_index_to_reg[index],
			       2, (u8 *)&meas_reg);
	ret = i2c_smbus_read_word_data(client, ak8975_index_to_reg[index]);
	if (ret < 0) {
		dev_err(&client->dev, "Read axis data fails\n");
		goto exit;
	}
	meas_reg = ret;

	mutex_unlock(&data->lock);

@@ -452,7 +418,6 @@ static int ak8975_probe(struct i2c_client *client,

	data->client = client;
	mutex_init(&data->lock);
	data->eoc_irq = client->irq;
	data->eoc_gpio = eoc_gpio;
	indio_dev->dev.parent = &client->dev;
	indio_dev->channels = ak8975_channels;
Loading