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

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

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

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

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

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

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

kyrsovik.doc

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

  279     idr_remove(&i2c_adapter_idr, adap->nr);

  280

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

  282

  283 out_unlock:

  284     up(&core_lists);

  285     return res;

  286 }

  287

  288

  289 /* -----

  290 * What follows is the "upwards" interface: commands for talking to clients,

  291 * which implement the functions to access the physical information of the

  292 * chips.

  293 */

  294

  295 int i2c_add_driver(struct i2c_driver *driver)

  296 {

  297     struct list_head   *item;

  298     struct i2c_adapter *adapter;

  299     int res = 0;

  300

  301     down(&core_lists);

  302

  303     /* add the driver to the list of i2c drivers in the driver core */

  304     driver->driver.owner = driver->owner;

  305     driver->driver.name = driver->name;

  306    driver->driver.bus = &i2c_bus_type;

  307     driver->driver.probe = i2c_device_probe;

  308     driver->driver.remove = i2c_device_remove;

  309

  310     res = driver_register(&driver->driver);

  311     if (res)

  312         goto out_unlock;

  313

  314     list_add_tail(&driver->list,&drivers);

  315     pr_debug("i2c-core: driver [%s] registered\n", driver->name);

  316

  317     /* now look for instances of driver on our adapters */

  318     if (driver->flags & I2C_DF_NOTIFY) {

  319         list_for_each(item,&adapters) {

  320             adapter = list_entry(item, struct i2c_adapter, list);

  321             driver->attach_adapter(adapter);

  322         }

  323     }

  324

  325 out_unlock:

  326     up(&core_lists);

  327     return res;

  328 }

  329

  330 int i2c_del_driver(struct i2c_driver *driver)

  331 {

  332     struct list_head   *item1, *item2, *_n;

  333     struct i2c_client  *client;

  334     struct i2c_adapter *adap;

  335

  336     int res = 0;

  337

  338     down(&core_lists);

  339

  340     /* Have a look at each adapter, if clients of this driver are still

  341      * attached. If so, detach them to be able to kill the driver

  342      * afterwards.

  343      *

  344      * Removing clients does not depend on the notify flag, else

  345      * invalid operation might (will!) result, when using stale client

  346      * pointers.

  347      */

  348     list_for_each(item1,&adapters) {

  349         adap = list_entry(item1, struct i2c_adapter, list);

  350        if (driver->detach_adapter) {

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

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

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

  354                 goto out_unlock;

  355             }

  356         } else {

  357             list_for_each_safe(item2, _n, &adap->clients) {

  358                 client = list_entry(item2, struct i2c_client, list);

  359                 if (client->driver != driver)

  360                     continue;

  361                 dev_dbg(&adap->dev, "detaching client [%s] "

  362                     "at 0x%02x\n", client->name,

  363                     client->addr);

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

  365                     dev_err(&adap->dev, "detach_client "

  366                         "failed for client [%s] at "

  367                         "0x%02x\n", client->name,

  368                         client->addr);

  369                     goto out_unlock;

  370                 }

  371             }

  372         }

  373     }

  374

  375     driver_unregister(&driver->driver);

  376     list_del(&driver->list);

  377     pr_debug("i2c-core: driver [%s] unregistered\n", driver->name);

  378

  379 out_unlock:

  380     up(&core_lists);

  381     return 0;

  382 }

  383

  384 static int __i2c_check_addr(struct i2c_adapter *adapter, unsigned int addr)

  385 {

  386     struct list_head   *item;

  387     struct i2c_client  *client;

  388

  389     list_for_each(item,&adapter->clients) {

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

  391         if (client->addr == addr)

  392             return -EBUSY;

  393     }

  394     return 0;

  395 }

  396

  397 int i2c_check_addr(struct i2c_adapter *adapter, int addr)

  398 {

  399     int rval;

  400

  401     down(&adapter->clist_lock);

  402     rval = __i2c_check_addr(adapter, addr);

  403     up(&adapter->clist_lock);

  404

  405     return rval;

  406 }

  407

  408 int i2c_attach_client(struct i2c_client *client)

  409 {

  410     struct i2c_adapter *adapter = client->adapter;

  411

  412     down(&adapter->clist_lock);

  413     if (__i2c_check_addr(client->adapter, client->addr)) {

  414         up(&adapter->clist_lock);

  415         return -EBUSY;

  416     }

  417     list_add_tail(&client->list,&adapter->clients);

  418     up(&adapter->clist_lock);

  419

  420     if (adapter->client_register)  {

  421         if (adapter->client_register(client))  {

  422             dev_dbg(&adapter->dev, "client_register "

  423                 "failed for client [%s] at 0x%02x\n",

  424                 client->name, client->addr);

  425         }

  426     }

  427

  428     if (client->flags & I2C_CLIENT_ALLOW_USE)

  429         client->usage_count = 0;

  430

  431     client->dev.parent = &client->adapter->dev;

  432     client->dev.driver = &client->driver->driver;

  433     client->dev.bus = &i2c_bus_type;

  434     client->dev.release = &i2c_client_release;

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