2016-10-05 7 views
3

У меня есть устройство i2c, встроенное в плату, для которой я разрабатываю. Он отвечает на один адрес, но первый байт (иногда называемый «команда» или «регистр») диктует функцию, адресованную.Написание модулей (я) ядра для многофункционального устройства i2c - одного или нескольких?

Я могу использовать устройство из пользовательского пространства с i2cset/get/detect, поэтому я знаю, что все работает.

Устройство управляет светодиодами (и поэтому должно появиться в /sys/class/leds).

Он также имеет GPIO (и поэтому должен появиться в /sys/class/gpio).

Есть еще полдюжины различных мест, где должны появляться функции устройства.

Должен ли я закодировать это как:

  1. Один модуль i2c клиента, и найти способ, чтобы получить вещи, перечисленные в нужных местах в /sys.
  2. Один модуль платформы и множество модулей драйверов, которые совместно используют одно устройство i2c (как-то) со своим кодом модуля в местах, специфичных для конкретной функции.

(Это мой первый модуль ядра, так как в конце-2,4 или ранней 2,6, это было очень давно.)

+1

Это трудно для меня точно настроить сообщения в ответ секции. До этого вы сможете поделиться именем/номером устройства, которое вы собираетесь использовать? Чтобы ответить на ваш вопрос, да, вам нужно написать драйвер для самого устройства в соответствующем слое. Например, напишите драйвер водить в linux/driver/leds /.Как сам по себе он экспортирует класс/sys/class/leds, вам может понадобиться понять основные слои ядра и написать поверх него. Я смогу ответить на конкретный вопрос, знаю ли я сам прибор. –

ответ

1

В источниках Линукс взглянуть на wm8350 модуль. Он состоит из одного базового модуля, связанного с шиной i2c и многих дочерних платформ, которые используют API-интерфейс модуля для доступа к регистрам чипов.

Основной модуль состоит из:

  • drivers/mfd/wm8350-i2c.c - связывают wm8350 к шине I2C
  • drivers/mfd/wm8350-core.c - создание устройств на платформе ребенка и предоставить API для дочерних устройств

GPIO модуль состоит из:

Во время инициализации основного модуля wm8350_i2c_probe() вызывается. Он вызывает wm8350_device_init(). Он создает дочерние платформы, используя wm8350_client_dev_register().

Детский модуль drivers/gpio/gpio-wm8350.c регистрируется как модуль для «платформы: wm8350-gpio», и его точка входа wm8350_gpio_probe().

Для того, чтобы получить доступ к основной модуль, модуль GPIO сделать:

107 static int wm8350_gpio_probe(struct platform_device *pdev) 
108 { 
109   struct wm8350 *wm8350 = dev_get_drvdata(pdev->dev.parent); 

И тогда он называет что-то вроде

36   return wm8350_set_bits(wm8350, WM8350_GPIO_CONFIGURATION_I_O, 
37        1 << offset); 
+0

В http://lxr.free-electrons.com/source/drivers/mfd/wm8350-core.c?v=4.4#L276 где создается 'struct wm8350'? Как ядро ​​знает, чтобы вызвать wm8350_device_init с указателем на него? (Я ранее использовал макрос 'module_init' в других модулях и не встречал' xxx_device_init' с аргументами.) – fadedbee

+0

Не беспокойтесь о комментарии выше. Я был под ложным впечатлением, что wm8350_core был тем, который был бы «init'ed» и начать других. http://lxr.free-electrons.com/source/drivers/mfd/wm8350-i2c.c?v=4.4#L48 показывает, что его модуль wm8350-i2c отвечает за «инициализацию» wm8350-core модуль. – fadedbee