brintos

brintos / linux-shallow public Read only

0
0
Text · 15.7 KiB · 3e0bf5d Raw
659 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Copyright (C) 2020 InvenSense, Inc.4 *5 * Driver for InvenSense ICP-1010xx barometric pressure and temperature sensor.6 *7 * Datasheet:8 * http://www.invensense.com/wp-content/uploads/2018/01/DS-000186-ICP-101xx-v1.2.pdf9 */10 11#include <linux/device.h>12#include <linux/module.h>13#include <linux/mod_devicetable.h>14#include <linux/i2c.h>15#include <linux/pm_runtime.h>16#include <linux/crc8.h>17#include <linux/mutex.h>18#include <linux/delay.h>19#include <linux/log2.h>20#include <linux/math64.h>21#include <linux/regulator/consumer.h>22#include <linux/iio/iio.h>23 24#define ICP10100_ID_REG_GET(_reg)	((_reg) & 0x003F)25#define ICP10100_ID_REG			0x0826#define ICP10100_RESPONSE_WORD_LENGTH	327#define ICP10100_CRC8_WORD_LENGTH	228#define ICP10100_CRC8_POLYNOMIAL	0x3129#define ICP10100_CRC8_INIT		0xFF30 31enum icp10100_mode {32	ICP10100_MODE_LP,	/* Low power mode: 1x sampling */33	ICP10100_MODE_N,	/* Normal mode: 2x sampling */34	ICP10100_MODE_LN,	/* Low noise mode: 4x sampling */35	ICP10100_MODE_ULN,	/* Ultra low noise mode: 8x sampling */36	ICP10100_MODE_NB,37};38 39struct icp10100_state {40	struct mutex lock;41	struct i2c_client *client;42	struct regulator *vdd;43	enum icp10100_mode mode;44	int16_t cal[4];45};46 47struct icp10100_command {48	__be16 cmd;49	unsigned long wait_us;50	unsigned long wait_max_us;51	size_t response_word_nb;52};53 54static const struct icp10100_command icp10100_cmd_soft_reset = {55	.cmd = cpu_to_be16(0x805D),56	.wait_us = 170,57	.wait_max_us = 200,58	.response_word_nb = 0,59};60 61static const struct icp10100_command icp10100_cmd_read_id = {62	.cmd = cpu_to_be16(0xEFC8),63	.wait_us = 0,64	.response_word_nb = 1,65};66 67static const struct icp10100_command icp10100_cmd_read_otp = {68	.cmd = cpu_to_be16(0xC7F7),69	.wait_us = 0,70	.response_word_nb = 1,71};72 73static const struct icp10100_command icp10100_cmd_measure[] = {74	[ICP10100_MODE_LP] = {75		.cmd = cpu_to_be16(0x401A),76		.wait_us = 1800,77		.wait_max_us = 2000,78		.response_word_nb = 3,79	},80	[ICP10100_MODE_N] = {81		.cmd = cpu_to_be16(0x48A3),82		.wait_us = 6300,83		.wait_max_us = 6500,84		.response_word_nb = 3,85	},86	[ICP10100_MODE_LN] = {87		.cmd = cpu_to_be16(0x5059),88		.wait_us = 23800,89		.wait_max_us = 24000,90		.response_word_nb = 3,91	},92	[ICP10100_MODE_ULN] = {93		.cmd = cpu_to_be16(0x58E0),94		.wait_us = 94500,95		.wait_max_us = 94700,96		.response_word_nb = 3,97	},98};99 100static const uint8_t icp10100_switch_mode_otp[] =101	{0xC5, 0x95, 0x00, 0x66, 0x9c};102 103DECLARE_CRC8_TABLE(icp10100_crc8_table);104 105static inline int icp10100_i2c_xfer(struct i2c_adapter *adap,106				    struct i2c_msg *msgs, int num)107{108	int ret;109 110	ret = i2c_transfer(adap, msgs, num);111	if (ret < 0)112		return ret;113 114	if (ret != num)115		return -EIO;116 117	return 0;118}119 120static int icp10100_send_cmd(struct icp10100_state *st,121			     const struct icp10100_command *cmd,122			     __be16 *buf, size_t buf_len)123{124	size_t size = cmd->response_word_nb * ICP10100_RESPONSE_WORD_LENGTH;125	uint8_t data[16];126	uint8_t *ptr;127	uint8_t *buf_ptr = (uint8_t *)buf;128	struct i2c_msg msgs[2] = {129		{130			.addr = st->client->addr,131			.flags = 0,132			.len = 2,133			.buf = (uint8_t *)&cmd->cmd,134		}, {135			.addr = st->client->addr,136			.flags = I2C_M_RD,137			.len = size,138			.buf = data,139		},140	};141	uint8_t crc;142	unsigned int i;143	int ret;144 145	if (size > sizeof(data))146		return -EINVAL;147 148	if (cmd->response_word_nb > 0 &&149			(buf == NULL || buf_len < (cmd->response_word_nb * 2)))150		return -EINVAL;151 152	dev_dbg(&st->client->dev, "sending cmd %#x\n", be16_to_cpu(cmd->cmd));153 154	if (cmd->response_word_nb > 0 && cmd->wait_us == 0) {155		/* direct command-response without waiting */156		ret = icp10100_i2c_xfer(st->client->adapter, msgs,157					ARRAY_SIZE(msgs));158		if (ret)159			return ret;160	} else {161		/* transfer command write */162		ret = icp10100_i2c_xfer(st->client->adapter, &msgs[0], 1);163		if (ret)164			return ret;165		if (cmd->wait_us > 0)166			usleep_range(cmd->wait_us, cmd->wait_max_us);167		/* transfer response read if needed */168		if (cmd->response_word_nb > 0) {169			ret = icp10100_i2c_xfer(st->client->adapter, &msgs[1], 1);170			if (ret)171				return ret;172		} else {173			return 0;174		}175	}176 177	/* process read words with crc checking */178	for (i = 0; i < cmd->response_word_nb; ++i) {179		ptr = &data[i * ICP10100_RESPONSE_WORD_LENGTH];180		crc = crc8(icp10100_crc8_table, ptr, ICP10100_CRC8_WORD_LENGTH,181			   ICP10100_CRC8_INIT);182		if (crc != ptr[ICP10100_CRC8_WORD_LENGTH]) {183			dev_err(&st->client->dev, "crc error recv=%#x calc=%#x\n",184				ptr[ICP10100_CRC8_WORD_LENGTH], crc);185			return -EIO;186		}187		*buf_ptr++ = ptr[0];188		*buf_ptr++ = ptr[1];189	}190 191	return 0;192}193 194static int icp10100_read_cal_otp(struct icp10100_state *st)195{196	__be16 val;197	int i;198	int ret;199 200	/* switch into OTP read mode */201	ret = i2c_master_send(st->client, icp10100_switch_mode_otp,202			      ARRAY_SIZE(icp10100_switch_mode_otp));203	if (ret < 0)204		return ret;205	if (ret != ARRAY_SIZE(icp10100_switch_mode_otp))206		return -EIO;207 208	/* read 4 calibration values */209	for (i = 0; i < 4; ++i) {210		ret = icp10100_send_cmd(st, &icp10100_cmd_read_otp,211					&val, sizeof(val));212		if (ret)213			return ret;214		st->cal[i] = be16_to_cpu(val);215		dev_dbg(&st->client->dev, "cal[%d] = %d\n", i, st->cal[i]);216	}217 218	return 0;219}220 221static int icp10100_init_chip(struct icp10100_state *st)222{223	__be16 val;224	uint16_t id;225	int ret;226 227	/* read and check id */228	ret = icp10100_send_cmd(st, &icp10100_cmd_read_id, &val, sizeof(val));229	if (ret)230		return ret;231	id = ICP10100_ID_REG_GET(be16_to_cpu(val));232	if (id != ICP10100_ID_REG) {233		dev_err(&st->client->dev, "invalid id %#x\n", id);234		return -ENODEV;235	}236 237	/* read calibration data from OTP */238	ret = icp10100_read_cal_otp(st);239	if (ret)240		return ret;241 242	/* reset chip */243	return icp10100_send_cmd(st, &icp10100_cmd_soft_reset, NULL, 0);244}245 246static int icp10100_get_measures(struct icp10100_state *st,247				uint32_t *pressure, uint16_t *temperature)248{249	const struct icp10100_command *cmd;250	__be16 measures[3];251	int ret;252 253	ret = pm_runtime_resume_and_get(&st->client->dev);254	if (ret < 0)255		return ret;256 257	mutex_lock(&st->lock);258	cmd = &icp10100_cmd_measure[st->mode];259	ret = icp10100_send_cmd(st, cmd, measures, sizeof(measures));260	mutex_unlock(&st->lock);261	if (ret)262		goto error_measure;263 264	*pressure = (be16_to_cpu(measures[0]) << 8) |265			(be16_to_cpu(measures[1]) >> 8);266	*temperature = be16_to_cpu(measures[2]);267 268	pm_runtime_mark_last_busy(&st->client->dev);269error_measure:270	pm_runtime_put_autosuspend(&st->client->dev);271	return ret;272}273 274static uint32_t icp10100_get_pressure(struct icp10100_state *st,275				      uint32_t raw_pressure, uint16_t raw_temp)276{277	static int32_t p_calib[] = {45000, 80000, 105000};278	static int32_t lut_lower = 3670016;279	static int32_t lut_upper = 12058624;280	static int32_t inv_quadr_factor = 16777216;281	static int32_t offset_factor = 2048;282	int64_t val1, val2;283	int32_t p_lut[3];284	int32_t t, t_square;285	int64_t a, b, c;286	uint32_t pressure_mPa;287 288	dev_dbg(&st->client->dev, "raw: pressure = %u, temp = %u\n",289		raw_pressure, raw_temp);290 291	/* compute p_lut values */292	t = (int32_t)raw_temp - 32768;293	t_square = t * t;294	val1 = (int64_t)st->cal[0] * (int64_t)t_square;295	p_lut[0] = lut_lower + (int32_t)div_s64(val1, inv_quadr_factor);296	val1 = (int64_t)st->cal[1] * (int64_t)t_square;297	p_lut[1] = offset_factor * st->cal[3] +298			(int32_t)div_s64(val1, inv_quadr_factor);299	val1 = (int64_t)st->cal[2] * (int64_t)t_square;300	p_lut[2] = lut_upper + (int32_t)div_s64(val1, inv_quadr_factor);301	dev_dbg(&st->client->dev, "p_lut = [%d, %d, %d]\n",302		p_lut[0], p_lut[1], p_lut[2]);303 304	/* compute a, b, c factors */305	val1 = (int64_t)p_lut[0] * (int64_t)p_lut[1] *306			(int64_t)(p_calib[0] - p_calib[1]) +307		(int64_t)p_lut[1] * (int64_t)p_lut[2] *308			(int64_t)(p_calib[1] - p_calib[2]) +309		(int64_t)p_lut[2] * (int64_t)p_lut[0] *310			(int64_t)(p_calib[2] - p_calib[0]);311	val2 = (int64_t)p_lut[2] * (int64_t)(p_calib[0] - p_calib[1]) +312		(int64_t)p_lut[0] * (int64_t)(p_calib[1] - p_calib[2]) +313		(int64_t)p_lut[1] * (int64_t)(p_calib[2] - p_calib[0]);314	c = div64_s64(val1, val2);315	dev_dbg(&st->client->dev, "val1 = %lld, val2 = %lld, c = %lld\n",316		val1, val2, c);317	val1 = (int64_t)p_calib[0] * (int64_t)p_lut[0] -318		(int64_t)p_calib[1] * (int64_t)p_lut[1] -319		(int64_t)(p_calib[1] - p_calib[0]) * c;320	val2 = (int64_t)p_lut[0] - (int64_t)p_lut[1];321	a = div64_s64(val1, val2);322	dev_dbg(&st->client->dev, "val1 = %lld, val2 = %lld, a = %lld\n",323		val1, val2, a);324	b = ((int64_t)p_calib[0] - a) * ((int64_t)p_lut[0] + c);325	dev_dbg(&st->client->dev, "b = %lld\n", b);326 327	/*328	 * pressure_Pa = a + (b / (c + raw_pressure))329	 * pressure_mPa = 1000 * pressure_Pa330	 */331	pressure_mPa = 1000LL * a + div64_s64(1000LL * b, c + raw_pressure);332 333	return pressure_mPa;334}335 336static int icp10100_read_raw_measures(struct iio_dev *indio_dev,337				      struct iio_chan_spec const *chan,338				      int *val, int *val2)339{340	struct icp10100_state *st = iio_priv(indio_dev);341	uint32_t raw_pressure;342	uint16_t raw_temp;343	uint32_t pressure_mPa;344	int ret;345 346	ret = iio_device_claim_direct_mode(indio_dev);347	if (ret)348		return ret;349 350	ret = icp10100_get_measures(st, &raw_pressure, &raw_temp);351	if (ret)352		goto error_release;353 354	switch (chan->type) {355	case IIO_PRESSURE:356		pressure_mPa = icp10100_get_pressure(st, raw_pressure,357						     raw_temp);358		/* mPa to kPa */359		*val = pressure_mPa / 1000000;360		*val2 = pressure_mPa % 1000000;361		ret = IIO_VAL_INT_PLUS_MICRO;362		break;363	case IIO_TEMP:364		*val = raw_temp;365		ret = IIO_VAL_INT;366		break;367	default:368		ret = -EINVAL;369		break;370	}371 372error_release:373	iio_device_release_direct_mode(indio_dev);374	return ret;375}376 377static int icp10100_read_raw(struct iio_dev *indio_dev,378			     struct iio_chan_spec const *chan,379			     int *val, int *val2, long mask)380{381	struct icp10100_state *st = iio_priv(indio_dev);382 383	switch (mask) {384	case IIO_CHAN_INFO_RAW:385	case IIO_CHAN_INFO_PROCESSED:386		return icp10100_read_raw_measures(indio_dev, chan, val, val2);387	case IIO_CHAN_INFO_SCALE:388		switch (chan->type) {389		case IIO_TEMP:390			/* 1000 * 175°C / 65536 in m°C */391			*val = 2;392			*val2 = 670288;393			return IIO_VAL_INT_PLUS_MICRO;394		default:395			return -EINVAL;396		}397		break;398	case IIO_CHAN_INFO_OFFSET:399		switch (chan->type) {400		case IIO_TEMP:401			/* 1000 * -45°C in m°C */402			*val = -45000;403			return IIO_VAL_INT;404		default:405			return -EINVAL;406		}407		break;408	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:409		mutex_lock(&st->lock);410		*val = 1 << st->mode;411		mutex_unlock(&st->lock);412		return IIO_VAL_INT;413	default:414		return -EINVAL;415	}416}417 418static int icp10100_read_avail(struct iio_dev *indio_dev,419			       struct iio_chan_spec const *chan,420			       const int **vals, int *type, int *length,421			       long mask)422{423	static int oversamplings[] = {1, 2, 4, 8};424 425	switch (mask) {426	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:427		*vals = oversamplings;428		*type = IIO_VAL_INT;429		*length = ARRAY_SIZE(oversamplings);430		return IIO_AVAIL_LIST;431	default:432		return -EINVAL;433	}434}435 436static int icp10100_write_raw(struct iio_dev *indio_dev,437			      struct iio_chan_spec const *chan,438			      int val, int val2, long mask)439{440	struct icp10100_state *st = iio_priv(indio_dev);441	unsigned int mode;442	int ret;443 444	switch (mask) {445	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:446		/* oversampling is always positive and a power of 2 */447		if (val <= 0 || !is_power_of_2(val))448			return -EINVAL;449		mode = ilog2(val);450		if (mode >= ICP10100_MODE_NB)451			return -EINVAL;452		ret = iio_device_claim_direct_mode(indio_dev);453		if (ret)454			return ret;455		mutex_lock(&st->lock);456		st->mode = mode;457		mutex_unlock(&st->lock);458		iio_device_release_direct_mode(indio_dev);459		return 0;460	default:461		return -EINVAL;462	}463}464 465static int icp10100_write_raw_get_fmt(struct iio_dev *indio_dev,466				      struct iio_chan_spec const *chan,467				      long mask)468{469	switch (mask) {470	case IIO_CHAN_INFO_OVERSAMPLING_RATIO:471		return IIO_VAL_INT;472	default:473		return -EINVAL;474	}475}476 477static const struct iio_info icp10100_info = {478	.read_raw = icp10100_read_raw,479	.read_avail = icp10100_read_avail,480	.write_raw = icp10100_write_raw,481	.write_raw_get_fmt = icp10100_write_raw_get_fmt,482};483 484static const struct iio_chan_spec icp10100_channels[] = {485	{486		.type = IIO_PRESSURE,487		.info_mask_separate = BIT(IIO_CHAN_INFO_PROCESSED),488		.info_mask_shared_by_all =489			BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),490		.info_mask_shared_by_all_available =491			BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),492	}, {493		.type = IIO_TEMP,494		.info_mask_separate = BIT(IIO_CHAN_INFO_RAW) |495			BIT(IIO_CHAN_INFO_SCALE) |496			BIT(IIO_CHAN_INFO_OFFSET),497		.info_mask_shared_by_all =498			BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),499		.info_mask_shared_by_all_available =500			BIT(IIO_CHAN_INFO_OVERSAMPLING_RATIO),501	},502};503 504static int icp10100_enable_regulator(struct icp10100_state *st)505{506	int ret;507 508	ret = regulator_enable(st->vdd);509	if (ret)510		return ret;511	msleep(100);512 513	return 0;514}515 516static void icp10100_disable_regulator_action(void *data)517{518	struct icp10100_state *st = data;519	int ret;520 521	ret = regulator_disable(st->vdd);522	if (ret)523		dev_err(&st->client->dev, "error %d disabling vdd\n", ret);524}525 526static void icp10100_pm_disable(void *data)527{528	struct device *dev = data;529 530	pm_runtime_disable(dev);531}532 533static int icp10100_probe(struct i2c_client *client)534{535	struct iio_dev *indio_dev;536	struct icp10100_state *st;537	int ret;538 539	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {540		dev_err(&client->dev, "plain i2c transactions not supported\n");541		return -ENODEV;542	}543 544	indio_dev = devm_iio_device_alloc(&client->dev, sizeof(*st));545	if (!indio_dev)546		return -ENOMEM;547 548	i2c_set_clientdata(client, indio_dev);549	indio_dev->name = client->name;550	indio_dev->modes = INDIO_DIRECT_MODE;551	indio_dev->channels = icp10100_channels;552	indio_dev->num_channels = ARRAY_SIZE(icp10100_channels);553	indio_dev->info = &icp10100_info;554 555	st = iio_priv(indio_dev);556	mutex_init(&st->lock);557	st->client = client;558	st->mode = ICP10100_MODE_N;559 560	st->vdd = devm_regulator_get(&client->dev, "vdd");561	if (IS_ERR(st->vdd))562		return PTR_ERR(st->vdd);563 564	ret = icp10100_enable_regulator(st);565	if (ret)566		return ret;567 568	ret = devm_add_action_or_reset(&client->dev,569				       icp10100_disable_regulator_action, st);570	if (ret)571		return ret;572 573	/* has to be done before the first i2c communication */574	crc8_populate_msb(icp10100_crc8_table, ICP10100_CRC8_POLYNOMIAL);575 576	ret = icp10100_init_chip(st);577	if (ret) {578		dev_err(&client->dev, "init chip error %d\n", ret);579		return ret;580	}581 582	/* enable runtime pm with autosuspend delay of 2s */583	pm_runtime_get_noresume(&client->dev);584	pm_runtime_set_active(&client->dev);585	pm_runtime_enable(&client->dev);586	pm_runtime_set_autosuspend_delay(&client->dev, 2000);587	pm_runtime_use_autosuspend(&client->dev);588	pm_runtime_put(&client->dev);589	ret = devm_add_action_or_reset(&client->dev, icp10100_pm_disable,590				       &client->dev);591	if (ret)592		return ret;593 594	return devm_iio_device_register(&client->dev, indio_dev);595}596 597static int icp10100_suspend(struct device *dev)598{599	struct icp10100_state *st = iio_priv(dev_get_drvdata(dev));600	int ret;601 602	mutex_lock(&st->lock);603	ret = regulator_disable(st->vdd);604	mutex_unlock(&st->lock);605 606	return ret;607}608 609static int icp10100_resume(struct device *dev)610{611	struct icp10100_state *st = iio_priv(dev_get_drvdata(dev));612	int ret;613 614	mutex_lock(&st->lock);615 616	ret = icp10100_enable_regulator(st);617	if (ret)618		goto out_unlock;619 620	/* reset chip */621	ret = icp10100_send_cmd(st, &icp10100_cmd_soft_reset, NULL, 0);622 623out_unlock:624	mutex_unlock(&st->lock);625	return ret;626}627 628static DEFINE_RUNTIME_DEV_PM_OPS(icp10100_pm, icp10100_suspend, icp10100_resume,629				 NULL);630 631static const struct of_device_id icp10100_of_match[] = {632	{633		.compatible = "invensense,icp10100",634	},635	{ }636};637MODULE_DEVICE_TABLE(of, icp10100_of_match);638 639static const struct i2c_device_id icp10100_id[] = {640	{ "icp10100" },641	{ }642};643MODULE_DEVICE_TABLE(i2c, icp10100_id);644 645static struct i2c_driver icp10100_driver = {646	.driver = {647		.name = "icp10100",648		.pm = pm_ptr(&icp10100_pm),649		.of_match_table = icp10100_of_match,650	},651	.probe = icp10100_probe,652	.id_table = icp10100_id,653};654module_i2c_driver(icp10100_driver);655 656MODULE_AUTHOR("InvenSense, Inc.");657MODULE_DESCRIPTION("InvenSense icp10100 driver");658MODULE_LICENSE("GPL");659