2019-05-30 02:57:44 +03:00
// SPDX-License-Identifier: GPL-2.0-only
2009-01-10 21:58:28 +03:00
/*
* Copyright 2008
* Guennadi Liakhovetski , DENX Software Engineering , < lg @ denx . de >
*
* LED driver for the DAC124S085 SPI DAC
*/
# include <linux/leds.h>
# include <linux/module.h>
# include <linux/mutex.h>
# include <linux/slab.h>
# include <linux/spi/spi.h>
struct dac124s085_led {
struct led_classdev ldev ;
struct spi_device * spi ;
int id ;
char name [ sizeof ( " dac124s085-3 " ) ] ;
struct mutex mutex ;
} ;
struct dac124s085 {
struct dac124s085_led leds [ 4 ] ;
} ;
# define REG_WRITE (0 << 12)
# define REG_WRITE_UPDATE (1 << 12)
# define ALL_WRITE_UPDATE (2 << 12)
# define POWER_DOWN_OUTPUT (3 << 12)
2015-08-20 13:47:25 +03:00
static int dac124s085_set_brightness ( struct led_classdev * ldev ,
enum led_brightness brightness )
2009-01-10 21:58:28 +03:00
{
2015-08-20 13:47:25 +03:00
struct dac124s085_led * led = container_of ( ldev , struct dac124s085_led ,
ldev ) ;
2009-01-10 21:58:28 +03:00
u16 word ;
2015-08-20 13:47:25 +03:00
int ret ;
2009-01-10 21:58:28 +03:00
mutex_lock ( & led - > mutex ) ;
word = cpu_to_le16 ( ( ( led - > id ) < < 14 ) | REG_WRITE_UPDATE |
2015-08-20 13:47:25 +03:00
( brightness & 0xfff ) ) ;
ret = spi_write ( led - > spi , ( const u8 * ) & word , sizeof ( word ) ) ;
2009-01-10 21:58:28 +03:00
mutex_unlock ( & led - > mutex ) ;
2015-08-20 13:47:25 +03:00
return ret ;
2009-01-10 21:58:28 +03:00
}
static int dac124s085_probe ( struct spi_device * spi )
{
struct dac124s085 * dac ;
struct dac124s085_led * led ;
int i , ret ;
2012-07-04 08:27:40 +04:00
dac = devm_kzalloc ( & spi - > dev , sizeof ( * dac ) , GFP_KERNEL ) ;
2009-01-10 21:58:28 +03:00
if ( ! dac )
return - ENOMEM ;
spi - > bits_per_word = 16 ;
for ( i = 0 ; i < ARRAY_SIZE ( dac - > leds ) ; i + + ) {
led = dac - > leds + i ;
led - > id = i ;
led - > spi = spi ;
snprintf ( led - > name , sizeof ( led - > name ) , " dac124s085-%d " , i ) ;
mutex_init ( & led - > mutex ) ;
led - > ldev . name = led - > name ;
led - > ldev . brightness = LED_OFF ;
led - > ldev . max_brightness = 0xfff ;
2015-08-20 13:47:25 +03:00
led - > ldev . brightness_set_blocking = dac124s085_set_brightness ;
2009-01-10 21:58:28 +03:00
ret = led_classdev_register ( & spi - > dev , & led - > ldev ) ;
if ( ret < 0 )
goto eledcr ;
}
spi_set_drvdata ( spi , dac ) ;
return 0 ;
eledcr :
while ( i - - )
led_classdev_unregister ( & dac - > leds [ i ] . ldev ) ;
return ret ;
}
static int dac124s085_remove ( struct spi_device * spi )
{
struct dac124s085 * dac = spi_get_drvdata ( spi ) ;
int i ;
2015-08-20 13:47:25 +03:00
for ( i = 0 ; i < ARRAY_SIZE ( dac - > leds ) ; i + + )
2009-01-10 21:58:28 +03:00
led_classdev_unregister ( & dac - > leds [ i ] . ldev ) ;
return 0 ;
}
static struct spi_driver dac124s085_driver = {
. probe = dac124s085_probe ,
. remove = dac124s085_remove ,
. driver = {
. name = " dac124s085 " ,
} ,
} ;
2012-01-11 03:09:30 +04:00
module_spi_driver ( dac124s085_driver ) ;
2009-01-10 21:58:28 +03:00
MODULE_AUTHOR ( " Guennadi Liakhovetski <lg@denx.de> " ) ;
MODULE_DESCRIPTION ( " DAC124S085 LED driver " ) ;
MODULE_LICENSE ( " GPL v2 " ) ;
2009-09-23 03:46:08 +04:00
MODULE_ALIAS ( " spi:dac124s085 " ) ;