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

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

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

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

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

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

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

kyrsovik.doc

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

  435

  436     snprintf(&client->dev.bus_id[0], sizeof(client->dev.bus_id),

  437         "%d-%04x", i2c_adapter_id(adapter), client->addr);

  438     dev_dbg(&adapter->dev, "client [%s] registered with bus id %s\n",

  439         client->name, client->dev.bus_id);

  440     device_register(&client->dev);

  441     device_create_file(&client->dev, &dev_attr_client_name);

  442

  443     return 0;

  444 }

  445

  446

  447 int i2c_detach_client(struct i2c_client *client)

  448 {

  449     struct i2c_adapter *adapter = client->adapter;

  450     int res = 0;

  451

  452     if ((client->flags & I2C_CLIENT_ALLOW_USE)

  453      && (client->usage_count > 0)) {

  454         dev_warn(&client->dev, "Client [%s] still busy, "

  455              "can't detach\n", client->name);

  456         return -EBUSY;

  457     }

  458

  459     if (adapter->client_unregister)  {

  460         res = adapter->client_unregister(client);

  461         if (res) {

  462             dev_err(&client->dev,

  463                 "client_unregister [%s] failed, "

  464                 "client not detached\n", client->name);

  465             goto out;

  466         }

  467     }

  468

  469     down(&adapter->clist_lock);

  470     list_del(&client->list);

  471     init_completion(&client->released);

  472     device_remove_file(&client->dev, &dev_attr_client_name);

  473     device_unregister(&client->dev);

  474     up(&adapter->clist_lock);

  475     wait_for_completion(&client->released);

  476

  477 out:

  478     return res;

  479 }

  480

  481 static int i2c_inc_use_client(struct i2c_client *client)

  482 {

  483

  484     if (!try_module_get(client->driver->owner))

  485         return -ENODEV;

  486     if (!try_module_get(client->adapter->owner)) {

  487         module_put(client->driver->owner);

  488         return -ENODEV;

  489     }

  490

  491     return 0;

  492 }

  493

  494 static void i2c_dec_use_client(struct i2c_client *client)

  495 {

  496     module_put(client->driver->owner);

  497     module_put(client->adapter->owner);

  498 }

  499

  500 int i2c_use_client(struct i2c_client *client)

  501 {

  502     int ret;

  503

  504     ret = i2c_inc_use_client(client);

  505     if (ret)

  506         return ret;

  507

  508     if (client->flags & I2C_CLIENT_ALLOW_USE) {

  509         if (client->flags & I2C_CLIENT_ALLOW_MULTIPLE_USE)

  510             client->usage_count++;

  511         else if (client->usage_count > 0)

  512             goto busy;

  513         else

  514             client->usage_count++;

  515     }

  516

  517     return 0;

  518 busy:

  519     i2c_dec_use_client(client);

  520     return -EBUSY;

  521 }

  522

  523 int i2c_release_client(struct i2c_client *client)

  524 {

  525     if(client->flags & I2C_CLIENT_ALLOW_USE) {

  526         if(client->usage_count>0)

  527             client->usage_count--;

  528         else {

  529             pr_debug("i2c-core: %s used one too many times\n",

  530                 __FUNCTION__);

  531             return -EPERM;

  532         }

  533     }

  534

  535     i2c_dec_use_client(client);

  536

  537     return 0;

  538 }

  539

  540 void i2c_clients_command(struct i2c_adapter *adap, unsigned int cmd, void

  541                          *arg)

  542 {

  543     struct list_head  *item;

  544     struct i2c_client *client;

  545

  546     down(&adap->clist_lock);

  547     list_for_each(item,&adap->clients) {

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

  549         if (!try_module_get(client->driver->owner))

  550             continue;

  551         if (NULL != client->driver->command) {

  552             up(&adap->clist_lock);

  553             client->driver->command(client,cmd,arg);

  554             down(&adap->clist_lock);

  555         }

  556         module_put(client->driver->owner);

  557        }

  558        up(&adap->clist_lock);

  559 }

  560

  561 static int __init i2c_init(void)

  562 {

  563     int retval;

  564

  565     retval = bus_register(&i2c_bus_type);

  566     if (retval)

  567         return retval;

  568     retval = driver_register(&i2c_adapter_driver);

  569     if (retval)

  570         return retval;

  571     return class_register(&i2c_adapter_class);

  572 }

  573

  574 static void __exit i2c_exit(void)

  575 {

  576     class_unregister(&i2c_adapter_class);

  577     driver_unregister(&i2c_adapter_driver);

  578     bus_unregister(&i2c_bus_type);

  579 }

  580

  581 subsys_initcall(i2c_init);

  582 module_exit(i2c_exit);

  583

  584 /* ----------------------------------------------------

  585 * the functional interface to the i2c busses.

  586 * ----------------------------------------------------

  587 */

  588

  589 int i2c_transfer(struct i2c_adapter * adap, struct i2c_msg *msgs, int num)

  590 {

  591     int ret;

  592

  593     if (adap->algo->master_xfer) {

  594 #ifdef DEBUG

  595         for (ret = 0; ret < num; ret++) {

  596             dev_dbg(&adap->dev, "master_xfer[%d] %c, addr=0x%02x, "

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