brintos

brintos / linux-shallow public Read only

0
0
Text · 2.4 KiB · cf5fb11 Raw
111 lines · c
1// SPDX-License-Identifier: GPL-2.0-only2/*3 * Copyright 20084 * Guennadi Liakhovetski, DENX Software Engineering, <lg@denx.de>5 *6 * LED driver for the DAC124S085 SPI DAC7 */8 9#include <linux/leds.h>10#include <linux/module.h>11#include <linux/mutex.h>12#include <linux/slab.h>13#include <linux/spi/spi.h>14 15struct dac124s085_led {16	struct led_classdev	ldev;17	struct spi_device	*spi;18	int			id;19	char			name[sizeof("dac124s085-3")];20 21	struct mutex		mutex;22};23 24struct dac124s085 {25	struct dac124s085_led leds[4];26};27 28#define REG_WRITE		(0 << 12)29#define REG_WRITE_UPDATE	(1 << 12)30#define ALL_WRITE_UPDATE	(2 << 12)31#define POWER_DOWN_OUTPUT	(3 << 12)32 33static int dac124s085_set_brightness(struct led_classdev *ldev,34				      enum led_brightness brightness)35{36	struct dac124s085_led *led = container_of(ldev, struct dac124s085_led,37						  ldev);38	u16 word;39	int ret;40 41	mutex_lock(&led->mutex);42	word = cpu_to_le16(((led->id) << 14) | REG_WRITE_UPDATE |43			   (brightness & 0xfff));44	ret = spi_write(led->spi, (const u8 *)&word, sizeof(word));45	mutex_unlock(&led->mutex);46 47	return ret;48}49 50static int dac124s085_probe(struct spi_device *spi)51{52	struct dac124s085	*dac;53	struct dac124s085_led	*led;54	int i, ret;55 56	dac = devm_kzalloc(&spi->dev, sizeof(*dac), GFP_KERNEL);57	if (!dac)58		return -ENOMEM;59 60	spi->bits_per_word = 16;61 62	for (i = 0; i < ARRAY_SIZE(dac->leds); i++) {63		led		= dac->leds + i;64		led->id		= i;65		led->spi	= spi;66		snprintf(led->name, sizeof(led->name), "dac124s085-%d", i);67		mutex_init(&led->mutex);68		led->ldev.name = led->name;69		led->ldev.brightness = LED_OFF;70		led->ldev.max_brightness = 0xfff;71		led->ldev.brightness_set_blocking = dac124s085_set_brightness;72		ret = led_classdev_register(&spi->dev, &led->ldev);73		if (ret < 0)74			goto eledcr;75	}76 77	spi_set_drvdata(spi, dac);78 79	return 0;80 81eledcr:82	while (i--)83		led_classdev_unregister(&dac->leds[i].ldev);84 85	return ret;86}87 88static void dac124s085_remove(struct spi_device *spi)89{90	struct dac124s085	*dac = spi_get_drvdata(spi);91	int i;92 93	for (i = 0; i < ARRAY_SIZE(dac->leds); i++)94		led_classdev_unregister(&dac->leds[i].ldev);95}96 97static struct spi_driver dac124s085_driver = {98	.probe		= dac124s085_probe,99	.remove		= dac124s085_remove,100	.driver = {101		.name	= "dac124s085",102	},103};104 105module_spi_driver(dac124s085_driver);106 107MODULE_AUTHOR("Guennadi Liakhovetski <lg@denx.de>");108MODULE_DESCRIPTION("DAC124S085 LED driver");109MODULE_LICENSE("GPL v2");110MODULE_ALIAS("spi:dac124s085");111