led子系统

 

led子系统
driver/leds/led-class.c
leds_init
 class_create
  static const struct attribute_group *led_groups[] = {
  &led_group,
  #ifdef CONFIG_LEDS_TRIGGERS
  &led_trigger_group,
  #endif
  NULL,
  };
led_classdev_unregister
led_classdev_register
devm_led_classdev_register
devm_led_classdev_release
driver/leds/led-core.c
led_sysfs_enable
led_update_brightness
led_blink_set_oneshot
led_blink_set
led_init_core
driver/leds/led-triggers.c
led_trigger_register_simple
led_trigger_event
led_trigger_register
led_trigger_set_default
led_trigger_store
include/linux/leds.h
driver/leds/trigger/ledtrig-camera.c
ledtrig_flash_ctrl
ledtrig_torch_ctrl
ledtrig_camera_init
driver/leds/trigger/ledtrig-oneshot.c

driver/leds/trigger/ledtrig-timer.c
driver/leds/trigger/ledtrig-heartbeat.c
container_of作用是通过结构体某个成员地址从而拿到整个结构体地址。
先看leds-sprd-gpio-rgb.c
sprd_leds_gpio_rgb_driver
 sprd_leds_gpio_rgb_probe
  of_get_gpio
  devm_gpio_request
  p->cdev.brightness_set = sprd_leds_gpio_rgb_set;
  led_classdev_register
sprd_leds_gpio_rgb_set
 container_of(led_cdev, struct sprd_leds_gpio_rgb, cdev)//通过结构体某个成员地址从而拿到整个结构体地址。
 sprd_leds_rgb_work
  sprd_leds_gpio_rgb_enable/sprd_leds_gpio_rgb_disable
再看leds-gpio.c
gpio_led_driver
 gpio_led_probe
 priv = gpio_leds_create(pdev);
  devm_get_gpiod_from_child
  fwnode_property_present(child, "label")
  fwnode_property_read_string(child, "linux,default-trigger",
         &led.default_trigger);
  fwnode_property_read_string(child, "default-state",
       &state)
  fwnode_property_present(child, "retain-state-suspended")
  create_gpio_led
   led_dat->cdev.default_trigger = template->default_trigger;
   led_dat->cdev.blink_set = gpio_blink_set;
   led_dat->cdev.brightness_set = gpio_led_set;
   ret = gpiod_direction_output(led_dat->gpiod, state); 
   INIT_WORK(&led_dat->work, gpio_led_work);
   return led_classdev_register(parent, &led_dat->cdev);
static void gpio_led_work(struct work_struct *work)
 led_dat->platform_gpio_blink_set(led_dat->gpiod,
     led_dat->new_level, NULL, NULL);
再看leds-lp8860.c
lp8860_driver
 lp8860_probe
  of_property_read_string(np, "label", &led->label)
  devm_gpiod_get_optional(&client->dev,
         "enable", GPIOD_OUT_LOW);
  led->regulator = devm_regulator_get(&client->dev, "vled");
  led->led_dev.brightness_set = lp8860_brightness_set;
  INIT_WORK(&led->work, lp8860_led_brightness_work);
  i2c_set_clientdata(client, led);
  lp8860_init
  ret = led_classdev_register(&client->dev, &led->led_dev);
lp8860_led_brightness_work
 ret = lp8860_fault_check(led);
 regmap_write
lp8860_brightness_set
 schedule_work(&led->work);
现在看led_classdev_register
led_classdev_register
 led_classdev_next_name
 device_create_with_groups
 list_add_tail
 led_update_brightness(led_cdev);
 led_init_core(led_cdev);
  INIT_WORK(&led_cdev->set_brightness_work, set_brightness_delayed);
  setup_timer(&led_cdev->blink_timer, led_timer_function,
      (unsigned long)led_cdev);
 led_trigger_set_default(led_cdev);
  led_trigger_set(led_cdev, trig);
再看ledtrig-gpio.c
gpio_trig_init
 led_trigger_register
  list_add_tail(&trig->next_trig, &trigger_list);
  led_trigger_set(led_cdev, trig);
   trig->activate(led_cdev);
    dev_attr_gpio
    dev_attr_inverted
    dev_attr_desired_brightness
    INIT_WORK(&gpio_data->work, gpio_trig_work);
dev_attr_gpio
 gpio_trig_gpio_show
  gpio_data->gpio
 gpio_trig_gpio_store
  request_irq(gpio_to_irq(gpio), gpio_trig_irq,
   IRQF_SHARED | IRQF_TRIGGER_RISING
   | IRQF_TRIGGER_FALLING, "ledtrig-gpio", led);
  gpio_data->gpio = gpio;
dev_attr_inverted
 gpio_trig_inverted_show
  gpio_data->inverted
 gpio_trig_inverted_store
  schedule_work(&gpio_data->work);
dev_attr_desired_brightness
 gpio_trig_brightness_show
  gpio_data->desired_brightness
 gpio_trig_brightness_store
  gpio_data->desired_brightness = desired_brightness;
所谓的led子系统,其实就是led和led-trigger相匹配。led设置设备的驱动,led-trigger来设置灯效触发方式。
设备驱动将led_cdev->node加到leds_list
然后list_for_each_entry(led_cdev, &leds_list, node) 找到leds_list的 led_cdev 执行led_trigger_set(led_cdev, NULL);
但是前提是需要一个led_dat->cdev.default_trigger存在。
 
 
 
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值