cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

leds-dac124s085.c (2451B)


      1// SPDX-License-Identifier: GPL-2.0-only
      2/*
      3 * Copyright 2008
      4 * Guennadi Liakhovetski, DENX Software Engineering, <lg@denx.de>
      5 *
      6 * LED driver for the DAC124S085 SPI DAC
      7 */
      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");