Исследование драйвера ядра Linux для шины I2C

Автор работы: Пользователь скрыл имя, 17 Января 2012 в 14:29, курсовая работа

Краткое описание

В настоящее время только Philips производит более 150 наименований I2C-совместимых устройств, функционально предназначенных работы в электронном оборудовании различного назначения. В их числе ИС памяти, видеопроцессоров и модулей обработки аудио- и видео-сигналов, АЦП и ЦАП, драйверы ЖК-индикаторов, процессоры со встоенным аппаратным контроллером I2C шины и многое другое.

Содержание работы

Введение 5
1 Шина управления I2C 10
2 Исследование драйвера 14
Заключение 15
Список использованных источников 16

Содержимое работы - 1 файл

kyrsovik.doc

— 337.00 Кб (Скачать файл)

  129 {

  130     struct i2c_client *client = to_i2c_client(dev);

  131     return sprintf(buf, "%s\n", client->name);

  132 }

  133

  134 /*

  135 * We can't use the DEVICE_ATTR() macro here as we want the same filename

  136                                 for a

  137 * different type of a device.  So beware if the DEVICE_ATTR() macro ever

  138 * changes, this definition will also have to change.

  139 */

  140 static struct device_attribute dev_attr_client_name = {

  141     .attr   = {.name = "name", .mode = S_IRUGO, .owner = THIS_MODULE },

  142     .show   = &show_client_name,

  143 };

  144

  145

  146 /* ---------------------------------------------------

  147 * registering functions

  148 * ---------------------------------------------------

  149 */

  150

  151 /* -----

  152 * i2c_add_adapter is called from within the algorithm layer,

  153 * when a new hw adapter registers. A new device is register to be

  154 * available for clients.

  155 */

  156 int i2c_add_adapter(struct i2c_adapter *adap)

  157 {

  158     int id, res = 0;

  159     struct list_head   *item;

  160     struct i2c_driver  *driver;

  161

  162     down(&core_lists);

  163

  164     if (idr_pre_get(&i2c_adapter_idr, GFP_KERNEL) == 0) {

  165         res = -ENOMEM;

  166         goto out_unlock;

  167     }

  168

  169     res = idr_get_new(&i2c_adapter_idr, adap, &id);

  170     if (res < 0) {

  171         if (res == -EAGAIN)

  172             res = -ENOMEM;

  173         goto out_unlock;

  174     }

  175

  176     adap->nr =  id & MAX_ID_MASK;

  177     init_MUTEX(&adap->bus_lock);

  178     init_MUTEX(&adap->clist_lock);

  179     list_add_tail(&adap->list,&adapters);

  180     INIT_LIST_HEAD(&adap->clients);

  181

  182     /* Add the adapter to the driver core.

  183      * If the parent pointer is not set up,

  184      * we add this adapter to the host bus.

  185      */

  186     if (adap->dev.parent == NULL)

  187         adap->dev.parent = &platform_bus;

  188     sprintf(adap->dev.bus_id, "i2c-%d", adap->nr);

  189     adap->dev.driver = &i2c_adapter_driver;

  190     adap->dev.release = &i2c_adapter_dev_release;

  191     device_register(&adap->dev);

  192     device_create_file(&adap->dev, &dev_attr_name);

  193

  194     /* Add this adapter to the i2c_adapter class */

  195     memset(&adap->class_dev, 0x00, sizeof(struct class_device));

  196     adap->class_dev.dev = &adap->dev;

  197     adap->class_dev.class = &i2c_adapter_class;

  198     strlcpy(adap->class_dev.class_id, adap->dev.bus_id, BUS_ID_SIZE);

  199     class_device_register(&adap->class_dev);

  200

  201     dev_dbg(&adap->dev, "adapter [%s] registered\n", adap->name);

  202

  203     /* inform drivers of new adapters */

  204     list_for_each(item,&drivers) {

  205         driver = list_entry(item, struct i2c_driver, list);

  206         if (driver->flags & I2C_DF_NOTIFY)

  207             /* We ignore the return code; if it fails, too bad */

  208             driver->attach_adapter(adap);

  209     }

  210

  211 out_unlock:

  212     up(&core_lists);

  213     return res;

  214 }

  215

  216

  217 int i2c_del_adapter(struct i2c_adapter *adap)

  218 {

  219     struct list_head  *item, *_n;

  220     struct i2c_adapter *adap_from_list;

  221     struct i2c_driver *driver;

  222     struct i2c_client *client;

  223     int res = 0;

  224

  225     down(&core_lists);

  226

  227     /* First make sure that this adapter was ever added */

  228     list_for_each_entry(adap_from_list, &adapters, list) {

  229         if (adap_from_list == adap)

  230             break;

  231     }

  232     if (adap_from_list != adap) {

  233         pr_debug("i2c-core: attempting to delete unregistered "

  234              "adapter [%s]\n", adap->name);

  235         res = -EINVAL;

  236         goto out_unlock;

  237     }

  238

  239     list_for_each(item,&drivers) {

  240         driver = list_entry(item, struct i2c_driver, list);

  241         if (driver->detach_adapter)

  242             if ((res = driver->detach_adapter(adap))) {

  243                 dev_err(&adap->dev, "detach_adapter failed "

  244                     "for driver [%s]\n", driver->name);

  245                 goto out_unlock;

  246             }

  247     }

  248

  249     /* detach any active clients. This must be done first, because

  250      * it can fail; in which case we give up. */

  251     list_for_each_safe(item, _n, &adap->clients) {

  252         client = list_entry(item, struct i2c_client, list);

  253

  254         /* detaching devices is unconditional of the set notify

  255          * flag, as _all_ clients that reside on the adapter

  256          * must be deleted, as this would cause invalid states.

  257          */

  258         if ((res=client->driver->detach_client(client))) {

  259             dev_err(&adap->dev, "detach_client failed for client "

  260                 "[%s] at address 0x%02x\n", client->name,

  261                 client->addr);

  262             goto out_unlock;

  263         }

  264     }

  265

  266     /* clean up the sysfs representation */

  267     init_completion(&adap->dev_released);

  268     init_completion(&adap->class_dev_released);

  269     class_device_unregister(&adap->class_dev);

  270     device_remove_file(&adap->dev, &dev_attr_name);

  271     device_unregister(&adap->dev);

  272     list_del(&adap->list);

  273

  274     /* wait for sysfs to drop all references */

  275     wait_for_completion(&adap->dev_released);

  276     wait_for_completion(&adap->class_dev_released);

  277

  278     /* free dynamically allocated bus id */

Информация о работе Исследование драйвера ядра Linux для шины I2C