26
26
#define UBNT_LEDBAR_MAX_BRIGHTNESS 0xff
27
27
28
28
#define UBNT_LEDBAR_TRANSACTION_LENGTH 8
29
- #define UBNT_LEDBAR_TRANSACTION_SUCCESS 0xaa
29
+ #define UBNT_LEDBAR_TRANSACTION_SUCCESS (char) 0xaa
30
30
31
31
#define UBNT_LEDBAR_TRANSACTION_BLUE_IDX 2
32
32
#define UBNT_LEDBAR_TRANSACTION_GREEN_IDX 3
33
33
#define UBNT_LEDBAR_TRANSACTION_RED_IDX 4
34
+ #define UBNT_LEDBAR_TRANSACTION_LED_COUNT_IDX 6
34
35
35
36
struct ubnt_ledbar {
36
37
struct mutex lock ;
38
+ u32 led_count ;
37
39
struct i2c_client * client ;
38
40
struct led_classdev led_red ;
39
41
struct led_classdev led_green ;
40
42
struct led_classdev led_blue ;
41
43
struct gpio_desc * enable_gpio ;
44
+ struct gpio_desc * reset_gpio ;
42
45
};
43
46
44
- static int ubnt_ledbar_perform_transaction (struct ubnt_ledbar * ledbar ,
45
- char * transaction )
47
+ static void ubnt_ledbar_perform_transaction (struct ubnt_ledbar * ledbar ,
48
+ const char * transaction , int len ,
49
+ char * result , int result_len )
46
50
{
47
- int ret ;
48
51
int i ;
49
52
50
- for (i = 0 ; i < UBNT_LEDBAR_TRANSACTION_LENGTH ; i ++ )
53
+ for (i = 0 ; i < len ; i ++ )
51
54
i2c_smbus_write_byte (ledbar -> client , transaction [i ]);
52
55
53
- return i2c_smbus_read_byte (ledbar -> client );
56
+ for (i = 0 ; i < result_len ; i ++ )
57
+ result [i ] = i2c_smbus_read_byte (ledbar -> client );
54
58
}
55
59
56
60
static int ubnt_ledbar_apply_state (struct ubnt_ledbar * ledbar )
57
61
{
58
62
char setup_msg [UBNT_LEDBAR_TRANSACTION_LENGTH ] = {0x40 , 0x10 , 0x00 , 0x00 ,
59
63
0x00 , 0x00 , 0x00 , 0x11 };
60
64
char led_msg [UBNT_LEDBAR_TRANSACTION_LENGTH ] = {0x40 , 0x00 , 0x00 , 0x00 ,
61
- 0x00 , 0x00 , 0x01 , 0x00 };
65
+ 0x00 , 0x00 , 0x00 , 0x00 };
62
66
char i2c_response ;
63
67
int ret = 0 ;
64
68
@@ -67,34 +71,63 @@ static int ubnt_ledbar_apply_state(struct ubnt_ledbar *ledbar)
67
71
led_msg [UBNT_LEDBAR_TRANSACTION_BLUE_IDX ] = ledbar -> led_blue .brightness ;
68
72
led_msg [UBNT_LEDBAR_TRANSACTION_GREEN_IDX ] = ledbar -> led_green .brightness ;
69
73
led_msg [UBNT_LEDBAR_TRANSACTION_RED_IDX ] = ledbar -> led_red .brightness ;
74
+ led_msg [UBNT_LEDBAR_TRANSACTION_LED_COUNT_IDX ] = ledbar -> led_count ;
70
75
71
- gpiod_set_raw_value (ledbar -> enable_gpio , 1 );
76
+ gpiod_set_value (ledbar -> enable_gpio , 1 );
72
77
73
78
msleep (10 );
74
79
75
- i2c_response = ubnt_ledbar_perform_transaction (ledbar , setup_msg );
80
+ ubnt_ledbar_perform_transaction (ledbar , setup_msg , sizeof ( setup_msg ), & i2c_response , sizeof ( i2c_response ) );
76
81
if (i2c_response != UBNT_LEDBAR_TRANSACTION_SUCCESS ) {
77
- dev_err (& ledbar -> client -> dev , "Error initializing LED transaction: %02x \n" , ret );
82
+ dev_err (& ledbar -> client -> dev , "Error initializing LED transaction: %02hhx \n" , i2c_response );
78
83
ret = - EINVAL ;
79
84
goto out_gpio ;
80
85
}
81
86
82
- i2c_response = ubnt_ledbar_perform_transaction (ledbar , led_msg );
87
+ ubnt_ledbar_perform_transaction (ledbar , led_msg , sizeof ( led_msg ), & i2c_response , sizeof ( i2c_response ) );
83
88
if (i2c_response != UBNT_LEDBAR_TRANSACTION_SUCCESS ) {
84
- dev_err (& ledbar -> client -> dev , "Failed LED transaction: %02x \n" , ret );
89
+ dev_err (& ledbar -> client -> dev , "Failed LED transaction: %02hhx \n" , i2c_response );
85
90
ret = - EINVAL ;
86
91
goto out_gpio ;
87
92
}
88
93
89
94
msleep (10 );
90
95
out_gpio :
91
- gpiod_set_raw_value (ledbar -> enable_gpio , 0 );
96
+ gpiod_set_value (ledbar -> enable_gpio , 0 );
92
97
93
98
mutex_unlock (& ledbar -> lock );
94
99
95
100
return ret ;
96
101
}
97
102
103
+ static void ubnt_ledbar_reset (struct ubnt_ledbar * ledbar )
104
+ {
105
+ static const char init_msg [16 ] = {0x02 , 0x81 , 0xfd , 0x7e ,
106
+ 0x00 , 0x00 , 0x00 , 0x00 ,
107
+ 0x00 , 0x00 , 0x00 , 0x00 ,
108
+ 0x00 , 0x00 , 0x00 , 0x00 };
109
+ char init_response [4 ];
110
+
111
+ if (!ledbar -> reset_gpio )
112
+ return ;
113
+
114
+ mutex_lock (& ledbar -> lock );
115
+
116
+ gpiod_set_value (ledbar -> reset_gpio , 1 );
117
+ msleep (10 );
118
+ gpiod_set_value (ledbar -> reset_gpio , 0 );
119
+
120
+ msleep (10 );
121
+
122
+ gpiod_set_value (ledbar -> enable_gpio , 1 );
123
+ msleep (10 );
124
+ ubnt_ledbar_perform_transaction (ledbar , init_msg , sizeof (init_msg ), init_response , sizeof (init_response ));
125
+ msleep (10 );
126
+ gpiod_set_value (ledbar -> enable_gpio , 0 );
127
+
128
+ mutex_unlock (& ledbar -> lock );
129
+ }
130
+
98
131
#define UBNT_LEDBAR_CONTROL_RGBS (name ) \
99
132
static int ubnt_ledbar_set_##name##_brightness(struct led_classdev *led_cdev,\
100
133
enum led_brightness value) \
@@ -153,14 +186,26 @@ static int ubnt_ledbar_probe(struct i2c_client *client,
153
186
return ret ;
154
187
}
155
188
156
- gpiod_direction_output (ledbar -> enable_gpio , 0 );
189
+ ledbar -> reset_gpio = devm_gpiod_get_optional (& client -> dev , "reset" , GPIOD_OUT_LOW );
190
+
191
+ if (IS_ERR (ledbar -> reset_gpio )) {
192
+ ret = PTR_ERR (ledbar -> reset_gpio );
193
+ dev_err (& client -> dev , "Failed to get reset gpio: %d\n" , ret );
194
+ return ret ;
195
+ }
196
+
197
+ ledbar -> led_count = 1 ;
198
+ of_property_read_u32 (np , "led-count" , & ledbar -> led_count );
157
199
158
200
ledbar -> client = client ;
159
201
160
202
mutex_init (& ledbar -> lock );
161
203
162
204
i2c_set_clientdata (client , ledbar );
163
205
206
+ // Reset and initialize the MCU
207
+ ubnt_ledbar_reset (ledbar );
208
+
164
209
ledbar -> led_red .brightness_set_blocking = ubnt_ledbar_set_red_brightness ;
165
210
ubnt_ledbar_init_led (of_get_child_by_name (np , "red" ), ledbar , & ledbar -> led_red );
166
211
0 commit comments