Linux driver development study notes [12]: Linux comes with LED light driver

table of Contents

1. The kernel comes with LED drive enable

Second, the kernel comes with LED driver analysis

Three, the kernel comes with LED driver to use


1. The kernel comes with LED drive enable

In the Linux kernel, the driver of the LED light is already provided, and the platform platform driver is used. Before use, you need to configure the kernel through make menuconfig to enable the driver of the LED light.

Save and exit will have multiple CONFIG_LEDS_GPIO=y macros in the .config configuration file in the directory , y means compiled into the kernel, if it is m means compiled into a module. After completion, use make -j4 to add the newly added LED driver to the kernel. Here is a trick to search for a certain content in the file: In the normal mode (press ESC), enter /, then enter the content you want to search, and press Enter to find the content you want to find.

CONFIG_LEDS_GPIO After the macro is defined, in / drivers / leds directory Makefile in leds-gpio.o  will be added into the compiled kernel.

There is also a reverse configuration method, that is, I know the name of the macro to be opened, how can I find the configuration items that can be enabled in the menuconfig:

1. Enter make menuconfig

2. Input /

3. Enter the macro you want to search (I searched here (CONFIG_LEDS_GPIO), press Enter, the following interface will appear, and then enter the corresponding label 1 before, it will jump to the interface to be configured

Second, the kernel comes with LED driver analysis

Open /drivers/leds/leds-gpio.c , this file is the LED driver source file that comes with the Linux kernel, and it uses the device tree to match the driver with the device's platform platform device driver. The driver will match the node in the device tree according to the compatible value in the of_gpio_leds_match matching table . If the corresponding device tree node is defined in the device, the gpio_led_probe function will be executed

static const struct of_device_id of_gpio_leds_match[] = {
	{ .compatible = "gpio-leds", },
	{},
};

MODULE_DEVICE_TABLE(of, of_gpio_leds_match);

static int gpio_led_probe(struct platform_device *pdev)
{
	struct gpio_led_platform_data *pdata = dev_get_platdata(&pdev->dev);
	struct gpio_leds_priv *priv;
	int i, ret = 0;

	if (pdata && pdata->num_leds) {
		priv = devm_kzalloc(&pdev->dev,
				sizeof_gpio_leds_priv(pdata->num_leds),
					GFP_KERNEL);
		if (!priv)
			return -ENOMEM;

		priv->num_leds = pdata->num_leds;
		for (i = 0; i < priv->num_leds; i++) {
			ret = create_gpio_led(&pdata->leds[i],
					      &priv->leds[i],
					      &pdev->dev, pdata->gpio_blink_set);
			if (ret < 0) {
				/* On failure: unwind the led creations */
				for (i = i - 1; i >= 0; i--)
					delete_gpio_led(&priv->leds[i]);
				return ret;
			}
		}
	} else {
		priv = gpio_leds_create(pdev);
		if (IS_ERR(priv))
			return PTR_ERR(priv);
	}

	platform_set_drvdata(pdev, priv);

	return 0;
}

static int gpio_led_remove(struct platform_device *pdev)
{
	struct gpio_leds_priv *priv = platform_get_drvdata(pdev);
	int i;

	for (i = 0; i < priv->num_leds; i++)
		delete_gpio_led(&priv->leds[i]);

	return 0;
}

static struct platform_driver gpio_led_driver = {
	.probe		= gpio_led_probe,
	.remove		= gpio_led_remove,
	.driver		= {
		.name	= "leds-gpio",
		.of_match_table = of_gpio_leds_match,
	},
};

/*同时完成了向内核注册和注销驱动的过程
 *platform_driver_register(&led_driver)
 *platform_driver_unregister(&led_driver)
*/
module_platform_driver(gpio_led_driver);

Three, the kernel comes with LED driver to use

1. First, compile the driver into the kernel

2. If there is a device tree, add the corresponding device tree node information in the .dts device tree according to the binding document;

If there is no device tree, you need to use platform_device_register to register the LED light device with the bus

According to the binding document, the added LED device tree nodes are as follows:

/*自行添加的Linux内核LED驱动*/
linux_leds {
compatible = "gpio-leds";
pinctrl-0 = <&pinctrl_gpio_leds>;/*pinctrl子系统*/
    led0 {
        label = "sysrun";
        gpios = <&gpio1 3 GPIO_ACTIVE_LOW>;
        linux,default-trigger = "heartbeat";
        default-state = "off";
    };
};

label : First name

gpios : gpio subsystem

linux,default-trigger : indicates the default trigger mode, there are several options as follows:

  1. "backlight" - LED will act as a back-light, controlled by the framebuffersystem
  2. "default-on" - LED will turn on (but for leds-gpio see "default-state"property in Documentation/devicetree/bindings/gpio/led.txt)
  3. "heartbeat" - LED "double" flashes at a load average based rate
  4. "ide-disk" - LED indicates disk activity
  5. "timer" - LED flashes at a fixed, configurable rate

3. Run the test

Enter the following command to update the device tree and restart the development board. At this time, the LED will flash twice as a heartbeat light and flash once at full speed. At the same time , you can see the added linux_leds node in the /sys/devices/platform directory

sudo cp arch/arm/boot/dts/imx6ull-alientek-emmc.dtb /home/denghengli/linux/tftp/ -f

If you want to control the LED on and off and modify the mode of the LED light, you can modify brightness and trigger to achieve

 

Guess you like

Origin blog.csdn.net/m0_37845735/article/details/107328682