brintos

brintos / linux-shallow public Read only

0
0
Text · 15.2 KiB · 1b47acf Raw
600 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * pca9532.c - 16-bit Led dimmer4 *5 * Copyright (C) 2011 Jan Weitzel6 * Copyright (C) 2008 Riku Voipio7 *8 * Datasheet: http://www.nxp.com/documents/data_sheet/PCA9532.pdf9 */10 11#include <linux/module.h>12#include <linux/i2c.h>13#include <linux/slab.h>14#include <linux/leds.h>15#include <linux/input.h>16#include <linux/mutex.h>17#include <linux/workqueue.h>18#include <linux/leds-pca9532.h>19#include <linux/gpio/driver.h>20#include <linux/of.h>21 22/* m =  num_leds*/23#define PCA9532_REG_INPUT(i)	((i) >> 3)24#define PCA9532_REG_OFFSET(m)	((m) >> 4)25#define PCA9532_REG_PSC(m, i)	(PCA9532_REG_OFFSET(m) + 0x1 + (i) * 2)26#define PCA9532_REG_PWM(m, i)	(PCA9532_REG_OFFSET(m) + 0x2 + (i) * 2)27#define LED_REG(m, led)		(PCA9532_REG_OFFSET(m) + 0x5 + (led >> 2))28#define LED_NUM(led)		(led & 0x3)29#define LED_SHIFT(led)		(LED_NUM(led) * 2)30#define LED_MASK(led)		(0x3 << LED_SHIFT(led))31 32#define PCA9532_PWM_PERIOD_DIV	15233#define PCA9532_PWM_DUTY_DIV	25634 35#define ldev_to_led(c)       container_of(c, struct pca9532_led, ldev)36 37struct pca9532_chip_info {38	u8	num_leds;39};40 41struct pca9532_data {42	struct i2c_client *client;43	struct pca9532_led leds[16];44	struct mutex update_lock;45	struct input_dev *idev;46	struct work_struct work;47#ifdef CONFIG_LEDS_PCA9532_GPIO48	struct gpio_chip gpio;49#endif50	const struct pca9532_chip_info *chip_info;51 52#define PCA9532_PWM_ID_0	053#define PCA9532_PWM_ID_1	154	u8 pwm[2];55	u8 psc[2];56	bool hw_blink;57};58 59static int pca9532_probe(struct i2c_client *client);60static void pca9532_remove(struct i2c_client *client);61 62enum {63	pca9530,64	pca9531,65	pca9532,66	pca9533,67};68 69static const struct i2c_device_id pca9532_id[] = {70	{ "pca9530", pca9530 },71	{ "pca9531", pca9531 },72	{ "pca9532", pca9532 },73	{ "pca9533", pca9533 },74	{ }75};76 77MODULE_DEVICE_TABLE(i2c, pca9532_id);78 79static const struct pca9532_chip_info pca9532_chip_info_tbl[] = {80	[pca9530] = {81		.num_leds = 2,82	},83	[pca9531] = {84		.num_leds = 8,85	},86	[pca9532] = {87		.num_leds = 16,88	},89	[pca9533] = {90		.num_leds = 4,91	},92};93 94#ifdef CONFIG_OF95static const struct of_device_id of_pca9532_leds_match[] = {96	{ .compatible = "nxp,pca9530", .data = (void *)pca9530 },97	{ .compatible = "nxp,pca9531", .data = (void *)pca9531 },98	{ .compatible = "nxp,pca9532", .data = (void *)pca9532 },99	{ .compatible = "nxp,pca9533", .data = (void *)pca9533 },100	{},101};102 103MODULE_DEVICE_TABLE(of, of_pca9532_leds_match);104#endif105 106static struct i2c_driver pca9532_driver = {107	.driver = {108		.name = "leds-pca953x",109		.of_match_table = of_match_ptr(of_pca9532_leds_match),110	},111	.probe = pca9532_probe,112	.remove = pca9532_remove,113	.id_table = pca9532_id,114};115 116/* We have two pwm/blinkers, but 16 possible leds to drive. Additionally,117 * the clever Thecus people are using one pwm to drive the beeper. So,118 * as a compromise we average one pwm to the values requested by all119 * leds that are not ON/OFF.120 * */121static int pca9532_calcpwm(struct i2c_client *client, int pwm, int blink,122	enum led_brightness value)123{124	int a = 0, b = 0, i = 0;125	struct pca9532_data *data = i2c_get_clientdata(client);126	for (i = 0; i < data->chip_info->num_leds; i++) {127		if (data->leds[i].type == PCA9532_TYPE_LED &&128			data->leds[i].state == PCA9532_PWM0+pwm) {129				a++;130				b += data->leds[i].ldev.brightness;131		}132	}133	if (a == 0) {134		dev_err(&client->dev,135		"fear of division by zero %d/%d, wanted %d\n",136			b, a, value);137		return -EINVAL;138	}139	b = b/a;140	if (b > 0xFF)141		return -EINVAL;142	data->pwm[pwm] = b;143	data->psc[pwm] = blink;144	return 0;145}146 147static int pca9532_setpwm(struct i2c_client *client, int pwm)148{149	struct pca9532_data *data = i2c_get_clientdata(client);150	u8 maxleds = data->chip_info->num_leds;151 152	mutex_lock(&data->update_lock);153	i2c_smbus_write_byte_data(client, PCA9532_REG_PWM(maxleds, pwm),154		data->pwm[pwm]);155	i2c_smbus_write_byte_data(client, PCA9532_REG_PSC(maxleds, pwm),156		data->psc[pwm]);157	mutex_unlock(&data->update_lock);158	return 0;159}160 161/* Set LED routing */162static void pca9532_setled(struct pca9532_led *led)163{164	struct i2c_client *client = led->client;165	struct pca9532_data *data = i2c_get_clientdata(client);166	u8 maxleds = data->chip_info->num_leds;167	char reg;168 169	mutex_lock(&data->update_lock);170	reg = i2c_smbus_read_byte_data(client, LED_REG(maxleds, led->id));171	/* zero led bits */172	reg = reg & ~LED_MASK(led->id);173	/* set the new value */174	reg = reg | (led->state << LED_SHIFT(led->id));175	i2c_smbus_write_byte_data(client, LED_REG(maxleds, led->id), reg);176	mutex_unlock(&data->update_lock);177}178 179static int pca9532_set_brightness(struct led_classdev *led_cdev,180	enum led_brightness value)181{182	int err = 0;183	struct pca9532_led *led = ldev_to_led(led_cdev);184 185	if (value == LED_OFF)186		led->state = PCA9532_OFF;187	else if (value == LED_FULL)188		led->state = PCA9532_ON;189	else {190		led->state = PCA9532_PWM0; /* Thecus: hardcode one pwm */191		err = pca9532_calcpwm(led->client, PCA9532_PWM_ID_0, 0, value);192		if (err)193			return err;194	}195	if (led->state == PCA9532_PWM0)196		pca9532_setpwm(led->client, PCA9532_PWM_ID_0);197	pca9532_setled(led);198	return err;199}200 201static int pca9532_update_hw_blink(struct pca9532_led *led,202				   unsigned long delay_on, unsigned long delay_off)203{204	struct pca9532_data *data = i2c_get_clientdata(led->client);205	unsigned int psc;206	int i;207 208	/* Look for others LEDs that already use PWM1 */209	for (i = 0; i < data->chip_info->num_leds; i++) {210		struct pca9532_led *other = &data->leds[i];211 212		if (other == led)213			continue;214 215		if (other->state == PCA9532_PWM1) {216			if (other->ldev.blink_delay_on != delay_on ||217			    other->ldev.blink_delay_off != delay_off) {218				/* HW can handle only one blink configuration at a time */219				return -EINVAL;220			}221		}222	}223 224	psc = ((delay_on + delay_off) * PCA9532_PWM_PERIOD_DIV - 1) / 1000;225	if (psc > U8_MAX) {226		/* Blink period too long to be handled by hardware */227		return -EINVAL;228	}229 230	led->state = PCA9532_PWM1;231	data->psc[PCA9532_PWM_ID_1] = psc;232	data->pwm[PCA9532_PWM_ID_1] = (delay_on * PCA9532_PWM_DUTY_DIV) / (delay_on + delay_off);233 234	return pca9532_setpwm(data->client, PCA9532_PWM_ID_1);235}236 237static int pca9532_set_blink(struct led_classdev *led_cdev,238	unsigned long *delay_on, unsigned long *delay_off)239{240	struct pca9532_led *led = ldev_to_led(led_cdev);241	struct i2c_client *client = led->client;242	struct pca9532_data *data = i2c_get_clientdata(client);243	int err;244 245	if (!data->hw_blink)246		return -EINVAL;247 248	if (*delay_on == 0 && *delay_off == 0) {249		/* led subsystem ask us for a blink rate */250		*delay_on = 500;251		*delay_off = 500;252	}253 254	err = pca9532_update_hw_blink(led, *delay_on, *delay_off);255	if (err)256		return err;257 258	pca9532_setled(led);259 260	return 0;261}262 263static int pca9532_event(struct input_dev *dev, unsigned int type,264	unsigned int code, int value)265{266	struct pca9532_data *data = input_get_drvdata(dev);267 268	if (!(type == EV_SND && (code == SND_BELL || code == SND_TONE)))269		return -1;270 271	/* XXX: allow different kind of beeps with psc/pwm modifications */272	if (value > 1 && value < 32767)273		data->pwm[PCA9532_PWM_ID_1] = 127;274	else275		data->pwm[PCA9532_PWM_ID_1] = 0;276 277	schedule_work(&data->work);278 279	return 0;280}281 282static void pca9532_input_work(struct work_struct *work)283{284	struct pca9532_data *data =285		container_of(work, struct pca9532_data, work);286	u8 maxleds = data->chip_info->num_leds;287 288	mutex_lock(&data->update_lock);289	i2c_smbus_write_byte_data(data->client, PCA9532_REG_PWM(maxleds, 1),290		data->pwm[PCA9532_PWM_ID_1]);291	mutex_unlock(&data->update_lock);292}293 294static enum pca9532_state pca9532_getled(struct pca9532_led *led)295{296	struct i2c_client *client = led->client;297	struct pca9532_data *data = i2c_get_clientdata(client);298	u8 maxleds = data->chip_info->num_leds;299	char reg;300	enum pca9532_state ret;301 302	mutex_lock(&data->update_lock);303	reg = i2c_smbus_read_byte_data(client, LED_REG(maxleds, led->id));304	ret = (reg & LED_MASK(led->id)) >> LED_SHIFT(led->id);305	mutex_unlock(&data->update_lock);306	return ret;307}308 309#ifdef CONFIG_LEDS_PCA9532_GPIO310static int pca9532_gpio_request_pin(struct gpio_chip *gc, unsigned offset)311{312	struct pca9532_data *data = gpiochip_get_data(gc);313	struct pca9532_led *led = &data->leds[offset];314 315	if (led->type == PCA9532_TYPE_GPIO)316		return 0;317 318	return -EBUSY;319}320 321static void pca9532_gpio_set_value(struct gpio_chip *gc, unsigned offset, int val)322{323	struct pca9532_data *data = gpiochip_get_data(gc);324	struct pca9532_led *led = &data->leds[offset];325 326	if (val)327		led->state = PCA9532_ON;328	else329		led->state = PCA9532_OFF;330 331	pca9532_setled(led);332}333 334static int pca9532_gpio_get_value(struct gpio_chip *gc, unsigned offset)335{336	struct pca9532_data *data = gpiochip_get_data(gc);337	unsigned char reg;338 339	reg = i2c_smbus_read_byte_data(data->client, PCA9532_REG_INPUT(offset));340 341	return !!(reg & (1 << (offset % 8)));342}343 344static int pca9532_gpio_direction_input(struct gpio_chip *gc, unsigned offset)345{346	/* To use as input ensure pin is not driven */347	pca9532_gpio_set_value(gc, offset, 0);348 349	return 0;350}351 352static int pca9532_gpio_direction_output(struct gpio_chip *gc, unsigned offset, int val)353{354	pca9532_gpio_set_value(gc, offset, val);355 356	return 0;357}358#endif /* CONFIG_LEDS_PCA9532_GPIO */359 360static void pca9532_destroy_devices(struct pca9532_data *data, int n_devs)361{362	int i = n_devs;363 364	while (--i >= 0) {365		switch (data->leds[i].type) {366		case PCA9532_TYPE_NONE:367		case PCA9532_TYPE_GPIO:368			break;369		case PCA9532_TYPE_LED:370			led_classdev_unregister(&data->leds[i].ldev);371			break;372		case PCA9532_TYPE_N2100_BEEP:373			if (data->idev != NULL) {374				cancel_work_sync(&data->work);375				data->idev = NULL;376			}377			break;378		}379	}380 381#ifdef CONFIG_LEDS_PCA9532_GPIO382	if (data->gpio.parent)383		gpiochip_remove(&data->gpio);384#endif385}386 387static int pca9532_configure(struct i2c_client *client,388	struct pca9532_data *data, struct pca9532_platform_data *pdata)389{390	int i, err = 0;391	int gpios = 0;392	u8 maxleds = data->chip_info->num_leds;393 394	for (i = 0; i < 2; i++)	{395		data->pwm[i] = pdata->pwm[i];396		data->psc[i] = pdata->psc[i];397		i2c_smbus_write_byte_data(client, PCA9532_REG_PWM(maxleds, i),398			data->pwm[i]);399		i2c_smbus_write_byte_data(client, PCA9532_REG_PSC(maxleds, i),400			data->psc[i]);401	}402 403	data->hw_blink = true;404	for (i = 0; i < data->chip_info->num_leds; i++) {405		struct pca9532_led *led = &data->leds[i];406		struct pca9532_led *pled = &pdata->leds[i];407		led->client = client;408		led->id = i;409		led->type = pled->type;410		switch (led->type) {411		case PCA9532_TYPE_NONE:412			break;413		case PCA9532_TYPE_GPIO:414			gpios++;415			break;416		case PCA9532_TYPE_LED:417			if (pled->state == PCA9532_KEEP)418				led->state = pca9532_getled(led);419			else420				led->state = pled->state;421			led->name = pled->name;422			led->ldev.name = led->name;423			led->ldev.default_trigger = pled->default_trigger;424			led->ldev.brightness = LED_OFF;425			led->ldev.brightness_set_blocking =426						pca9532_set_brightness;427			led->ldev.blink_set = pca9532_set_blink;428			err = led_classdev_register(&client->dev, &led->ldev);429			if (err < 0) {430				dev_err(&client->dev,431					"couldn't register LED %s\n",432					led->name);433				goto exit;434			}435			pca9532_setled(led);436			break;437		case PCA9532_TYPE_N2100_BEEP:438			/* PWM1 is reserved for beeper so blink will not use hardware */439			data->hw_blink = false;440			BUG_ON(data->idev);441			led->state = PCA9532_PWM1;442			pca9532_setled(led);443			data->idev = devm_input_allocate_device(&client->dev);444			if (data->idev == NULL) {445				err = -ENOMEM;446				goto exit;447			}448			data->idev->name = pled->name;449			data->idev->phys = "i2c/pca9532";450			data->idev->id.bustype = BUS_HOST;451			data->idev->id.vendor = 0x001f;452			data->idev->id.product = 0x0001;453			data->idev->id.version = 0x0100;454			data->idev->evbit[0] = BIT_MASK(EV_SND);455			data->idev->sndbit[0] = BIT_MASK(SND_BELL) |456						BIT_MASK(SND_TONE);457			data->idev->event = pca9532_event;458			input_set_drvdata(data->idev, data);459			INIT_WORK(&data->work, pca9532_input_work);460			err = input_register_device(data->idev);461			if (err) {462				cancel_work_sync(&data->work);463				data->idev = NULL;464				goto exit;465			}466			break;467		}468	}469 470#ifdef CONFIG_LEDS_PCA9532_GPIO471	if (gpios) {472		data->gpio.label = "gpio-pca9532";473		data->gpio.direction_input = pca9532_gpio_direction_input;474		data->gpio.direction_output = pca9532_gpio_direction_output;475		data->gpio.set = pca9532_gpio_set_value;476		data->gpio.get = pca9532_gpio_get_value;477		data->gpio.request = pca9532_gpio_request_pin;478		data->gpio.can_sleep = 1;479		data->gpio.base = pdata->gpio_base;480		data->gpio.ngpio = data->chip_info->num_leds;481		data->gpio.parent = &client->dev;482		data->gpio.owner = THIS_MODULE;483 484		err = gpiochip_add_data(&data->gpio, data);485		if (err) {486			/* Use data->gpio.dev as a flag for freeing gpiochip */487			data->gpio.parent = NULL;488			dev_warn(&client->dev, "could not add gpiochip\n");489		} else {490			dev_info(&client->dev, "gpios %i...%i\n",491				data->gpio.base, data->gpio.base +492				data->gpio.ngpio - 1);493		}494	}495#endif496 497	return 0;498 499exit:500	pca9532_destroy_devices(data, i);501	return err;502}503 504static struct pca9532_platform_data *505pca9532_of_populate_pdata(struct device *dev, struct device_node *np)506{507	struct pca9532_platform_data *pdata;508	int devid, maxleds;509	int i = 0;510	const char *state;511 512	devid = (int)(uintptr_t)of_device_get_match_data(dev);513	maxleds = pca9532_chip_info_tbl[devid].num_leds;514 515	pdata = devm_kzalloc(dev, sizeof(*pdata), GFP_KERNEL);516	if (!pdata)517		return ERR_PTR(-ENOMEM);518 519	pdata->gpio_base = -1;520 521	of_property_read_u8_array(np, "nxp,pwm", &pdata->pwm[PCA9532_PWM_ID_0],522				  ARRAY_SIZE(pdata->pwm));523	of_property_read_u8_array(np, "nxp,psc", &pdata->psc[PCA9532_PWM_ID_0],524				  ARRAY_SIZE(pdata->psc));525 526	for_each_available_child_of_node_scoped(np, child) {527		if (of_property_read_string(child, "label",528					    &pdata->leds[i].name))529			pdata->leds[i].name = child->name;530		of_property_read_u32(child, "type", &pdata->leds[i].type);531		of_property_read_string(child, "linux,default-trigger",532					&pdata->leds[i].default_trigger);533		if (!of_property_read_string(child, "default-state", &state)) {534			if (!strcmp(state, "on"))535				pdata->leds[i].state = PCA9532_ON;536			else if (!strcmp(state, "keep"))537				pdata->leds[i].state = PCA9532_KEEP;538		}539		if (++i >= maxleds)540			break;541	}542 543	return pdata;544}545 546static int pca9532_probe(struct i2c_client *client)547{548	const struct i2c_device_id *id = i2c_client_get_device_id(client);549	int devid;550	struct pca9532_data *data = i2c_get_clientdata(client);551	struct pca9532_platform_data *pca9532_pdata =552			dev_get_platdata(&client->dev);553	struct device_node *np = dev_of_node(&client->dev);554 555	if (!pca9532_pdata) {556		if (np) {557			pca9532_pdata =558				pca9532_of_populate_pdata(&client->dev, np);559			if (IS_ERR(pca9532_pdata))560				return PTR_ERR(pca9532_pdata);561		} else {562			dev_err(&client->dev, "no platform data\n");563			return -EINVAL;564		}565		devid = (int)(uintptr_t)of_device_get_match_data(&client->dev);566	} else {567		devid = id->driver_data;568	}569 570	if (!i2c_check_functionality(client->adapter,571		I2C_FUNC_SMBUS_BYTE_DATA))572		return -EIO;573 574	data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);575	if (!data)576		return -ENOMEM;577 578	data->chip_info = &pca9532_chip_info_tbl[devid];579 580	dev_info(&client->dev, "setting platform data\n");581	i2c_set_clientdata(client, data);582	data->client = client;583	mutex_init(&data->update_lock);584 585	return pca9532_configure(client, data, pca9532_pdata);586}587 588static void pca9532_remove(struct i2c_client *client)589{590	struct pca9532_data *data = i2c_get_clientdata(client);591 592	pca9532_destroy_devices(data, data->chip_info->num_leds);593}594 595module_i2c_driver(pca9532_driver);596 597MODULE_AUTHOR("Riku Voipio");598MODULE_LICENSE("GPL");599MODULE_DESCRIPTION("PCA 9532 LED dimmer");600