2 * device-manager-plugin-rpi3
4 * Copyright (c) 2017 Samsung Electronics Co., Ltd.
6 * Licensed under the Apache License, Version 2.0 (the License);
7 * you may not use this file except in compliance with the License.
8 * You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
23 #include <hal/device/hal-led-interface.h>
24 #include <hal/hal-common-interface.h>
27 #include <peripheral_io.h>
29 #define GET_BRIGHTNESS(val) (((val) >> 24) & 0xFF)
31 #define GET_TYPE(a) (((a) >> 24) & 0xFF)
32 #define GET_RED_ONLY(a) ((a) & 0xFF0000)
33 #define GET_GREEN_ONLY(a) ((a) & 0x00FF00)
34 #define GET_BLUE_ONLY(a) ((a) & 0x0000FF)
35 #define GET_RED_BRT(a) (uint8_t)(((a) >> 16) & 0xFF)
36 #define GET_GREEN_BRT(a) (uint8_t)(((a) >> 8) & 0xFF)
37 #define GET_BLUE_BRT(a) (uint8_t)((a) & 0xFF)
42 #define GPIO_I2C_BUS_INDEX 1
43 #define BLINKM_DEFAULT_ADDR 0x09
46 * LED operation command code
47 * Stop script: 0x6f('o')
48 * Set command: 0x6e('n')
49 * Change address command: 0x41('A')
51 #define SET_CMD_CODE 0x6e
52 #define STOP_SCRIPT_CMD 0x6f
53 #define CHANGE_ADDR_CMD 0x41
55 typedef enum _led_rgb_type {
61 struct gpio_rgb_play_color_info {
66 struct gpio_rgb_play_info {
73 static uint8_t off_cmd[4] = { SET_CMD_CODE, 0x00, 0x00, 0x00 };
75 static void blinkm_led_stop_script(peripheral_i2c_h handle)
77 uint8_t data[1] = {STOP_SCRIPT_CMD};
80 peripheral_i2c_write(handle, data, length);
86 static void blinkm_led_off(peripheral_i2c_h handle)
88 peripheral_i2c_write(handle, off_cmd, sizeof(off_cmd));
91 static void blinkm_led_init(peripheral_i2c_h handle)
93 blinkm_led_stop_script(handle);
94 blinkm_led_off(handle);
97 static void blinkm_led_set_color(peripheral_i2c_h handle, uint8_t *pkt_data, int len)
99 peripheral_i2c_write(handle, pkt_data, len);
102 static int gpio_led_open_device(int device_index, peripheral_i2c_h *device_handle)
106 if ((ret = peripheral_i2c_open(device_index, BLINKM_DEFAULT_ADDR, device_handle)) < PERIPHERAL_ERROR_NONE) {
107 _E("Failed to open I2C");
112 static int gpio_led_close_device(peripheral_i2c_h device_handle)
116 if ((ret = peripheral_i2c_close(device_handle)) < PERIPHERAL_ERROR_NONE) {
117 _E("Failed to close I2C");
122 static int gpio_rgb_set_brightness(struct led_state *state)
124 uint8_t cmd_pkt[4] = { SET_CMD_CODE, };
125 peripheral_i2c_h handle;
132 color = state->color;
134 cmd_pkt[1] = GET_RED_BRT(color);
135 cmd_pkt[2] = GET_GREEN_BRT(color);
136 cmd_pkt[3] = GET_BLUE_BRT(color);
138 _I("COLOR(%x) r(%x), g(%x), b(%x)", color, cmd_pkt[1], cmd_pkt[2], cmd_pkt[3]);
140 if ((ret = gpio_led_open_device(GPIO_I2C_BUS_INDEX, &handle)) < PERIPHERAL_ERROR_NONE)
143 blinkm_led_set_color(handle, cmd_pkt, sizeof(cmd_pkt));
145 if ((ret = gpio_led_close_device(handle)) < PERIPHERAL_ERROR_NONE)
152 static int gpio_rgb_turn_off(struct led_state *state)
154 struct led_state st = { LED_TYPE_MANUAL, };
155 return gpio_rgb_set_brightness(&st);
158 /* release play list */
159 static void free_func(gpointer data)
161 struct gpio_rgb_play_color_info *color = data;
165 static void release_play_info(void)
167 if (play_info.play_list) {
168 g_list_free_full(play_info.play_list, free_func);
169 play_info.play_list = NULL;
171 play_info.nr_play = 0;
173 if (play_info.timer) {
174 g_source_remove(play_info.timer);
178 gpio_rgb_turn_off(NULL);
181 static int gpio_rgb_init_led()
183 peripheral_i2c_h handle;
186 if ((ret = gpio_led_open_device(GPIO_I2C_BUS_INDEX, &handle)) < PERIPHERAL_ERROR_NONE)
189 blinkm_led_init(handle);
191 if ((ret = gpio_led_close_device(handle)) < PERIPHERAL_ERROR_NONE)
197 /* timer callback to change colors which are stored in play_list */
198 static gboolean gpio_rgb_timer_expired(gpointer data)
200 struct gpio_rgb_play_color_info *color;
201 struct led_state state = {LED_TYPE_MANUAL, };
204 if (play_info.timer) {
205 g_source_remove(play_info.timer);
209 color = g_list_nth_data(play_info.play_list, play_info.index);
211 _E("Failed to get (%d)th item from the play list", play_info.index);
215 play_info.timer = g_timeout_add(color->time, gpio_rgb_timer_expired, data);
216 if (play_info.timer == 0) {
217 _E("Failed to add timeout for LED blinking");
221 state.color = color->color;
223 ret = gpio_rgb_set_brightness(&state);
225 _E("Failed to set brightness (%d)", ret);
230 if (play_info.index == play_info.nr_play)
233 return G_SOURCE_CONTINUE;
238 return G_SOURCE_REMOVE;
241 /* insert color info to the play_list */
242 static int gpio_rgb_insert_play_list(unsigned color, int on, int off)
244 struct gpio_rgb_play_color_info *on_info, *off_info;
248 on_info = calloc(1, sizeof(struct gpio_rgb_play_color_info));
251 off_info = calloc(1, sizeof(struct gpio_rgb_play_color_info));
257 on_info->color = color;
259 play_info.play_list = g_list_append(play_info.play_list, on_info);
262 off_info->time = off;
263 play_info.play_list = g_list_append(play_info.play_list, off_info);
268 /* insert color info to the play list and start to play */
269 static int gpio_rgb_set_brightness_blink(struct led_state *state)
274 val = GET_RED_ONLY(state->color);
276 ret = gpio_rgb_insert_play_list(val, state->duty_on, state->duty_off);
278 _E("Failed to insert color info to list (%d)", ret);
280 val = GET_GREEN_ONLY(state->color);
282 ret = gpio_rgb_insert_play_list(val, state->duty_on, state->duty_off);
284 _E("Failed to insert color info to list (%d)", ret);
286 val = GET_BLUE_ONLY(state->color);
288 ret = gpio_rgb_insert_play_list(val, state->duty_on, state->duty_off);
290 _E("Failed to insert color info to list (%d)", ret);
293 play_info.nr_play = g_list_length(play_info.play_list);
296 gpio_rgb_timer_expired(NULL);
300 static int gpio_rgb_turn_on(struct led_state *state)
302 if (state->type == LED_TYPE_MANUAL)
303 return gpio_rgb_set_brightness(state);
305 return gpio_rgb_set_brightness_blink(state);
308 static int gpio_rgb_set_state(struct led_state *state)
313 switch (state->type) {
315 case LED_TYPE_MANUAL:
318 _E("Not suppoted type (%d)", state->type);
323 if (GET_TYPE(state->color) == 0)
324 return gpio_rgb_turn_off(state);
326 return gpio_rgb_turn_on(state);
329 static int led_init(void **data)
331 hal_backend_led_funcs *led_funcs;
333 led_funcs = calloc(1, sizeof(hal_backend_led_funcs));
337 if (gpio_rgb_init_led()) {
341 led_funcs->set_state = gpio_rgb_set_state;
343 *data = (void *)led_funcs;
348 static int led_exit(void *data)
357 hal_backend EXPORT hal_backend_device_led_data = {
360 .abi_version = HAL_ABI_VERSION_TIZEN_6_5,