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

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

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

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

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

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

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

kyrsovik.doc

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

  750     if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_QUICK)) {

  751         if (address_data->probe[0] == I2C_CLIENT_END

  752          && address_data->normal_i2c[0] == I2C_CLIENT_END)

  753             return 0;

  754

  755         dev_warn(&adapter->dev, "SMBus Quick command not supported, "

  756              "can't probe for chips\n");

  757         return -1;

  758     }

  759

  760     /* Probe entries are done second, and are not affected by ignore

  761        entries either */

  762     for (i = 0; address_data->probe[i] != I2C_CLIENT_END; i += 2) {

  763         if (address_data->probe[i] == adap_id

  764          || address_data->probe[i] == ANY_I2C_BUS) {

  765             dev_dbg(&adapter->dev, "found probe parameter for "

  766                 "adapter %d, addr 0x%02x\n", adap_id,

  767                 address_data->probe[i + 1]);

  768             err = i2c_probe_address(adapter,

  769                         address_data->probe[i + 1],

  770                         -1, found_proc);

  771             if (err)

  772                 return err;

  773         }

  774     }

  775

  776     /* Normal entries are done last, unless shadowed by an ignore entry */

  777     for (i = 0; address_data->normal_i2c[i] != I2C_CLIENT_END; i += 1) {

  778         int j, ignore;

  779

  780         ignore = 0;

  781         for (j = 0; address_data->ignore[j] != I2C_CLIENT_END;

  782              j += 2) {

  783             if ((address_data->ignore[j] == adap_id ||

  784                  address_data->ignore[j] == ANY_I2C_BUS)

  785              && address_data->ignore[j + 1]

  786                 == address_data->normal_i2c[i]) {

  787                 dev_dbg(&adapter->dev, "found ignore "

  788                     "parameter for adapter %d, "

  789                     "addr 0x%02x\n", adap_id,

  790                     address_data->ignore[j + 1]);

  791             }

  792             ignore = 1;

  793             break;

  794         }

  795         if (ignore)

  796             continue;

  797

  798         dev_dbg(&adapter->dev, "found normal entry for adapter %d, "

  799             "addr 0x%02x\n", adap_id,

  800             address_data->normal_i2c[i]);

  801         err = i2c_probe_address(adapter, address_data->normal_i2c[i],

  802                     -1, found_proc);

  803         if (err)

  804             return err;

  805     }

  806

  807     return 0;

  808 }

  809

  810 struct i2c_adapter* i2c_get_adapter(int id)

  811 {

  812     struct i2c_adapter *adapter;

  813

  814     down(&core_lists);

  815     adapter = (struct i2c_adapter *)idr_find(&i2c_adapter_idr, id);

  816     if (adapter && !try_module_get(adapter->owner))

  817         adapter = NULL;

  818

  819     up(&core_lists);

  820     return adapter;

  821 }

  822

  823 void i2c_put_adapter(struct i2c_adapter *adap)

  824 {

  825     module_put(adap->owner);

  826 }

  827

  828 /* The SMBus parts */

  829

  830 #define POLY    (0x1070U << 3)

  831 static u8

  832 crc8(u16 data)

  833 {

  834     int i;

  835

  836     for(i = 0; i < 8; i++) {

  837         if (data & 0x8000)

  838             data = data ^ POLY;

  839         data = data << 1;

  840     }

  841     return (u8)(data >> 8);

  842 }

  843

  844 /* Incremental CRC8 over count bytes in the array pointed to by p */

  845 static u8 i2c_smbus_pec(u8 crc, u8 *p, size_t count)

  846 {

  847     int i;

  848

  849     for(i = 0; i < count; i++)

  850         crc = crc8((crc ^ p[i]) << 8);

  851     return crc;

  852 }

  853

  854 /* Assume a 7-bit address, which is reasonable for SMBus */

  855 static u8 i2c_smbus_msg_pec(u8 pec, struct i2c_msg *msg)

  856 {

  857     /* The address will be sent first */

  858     u8 addr = (msg->addr << 1) | !!(msg->flags & I2C_M_RD);

  859     pec = i2c_smbus_pec(pec, &addr, 1);

  860

  861     /* The data buffer follows */

  862     return i2c_smbus_pec(pec, msg->buf, msg->len);

  863 }

  864

  865 /* Used for write only transactions */

  866 static inline void i2c_smbus_add_pec(struct i2c_msg *msg)

  867 {

  868     msg->buf[msg->len] = i2c_smbus_msg_pec(0, msg);

  869     msg->len++;

  870 }

  871

  872 /* Return <0 on CRC error

  873    If there was a write before this read (most cases) we need to take the

  874    partial CRC from the write part into account.

  875    Note that this function does modify the message (we need to decrease the

  876    message length to hide the CRC byte from the caller). */

  877 static int i2c_smbus_check_pec(u8 cpec, struct i2c_msg *msg)

  878 {

  879     u8 rpec = msg->buf[--msg->len];

  880     cpec = i2c_smbus_msg_pec(cpec, msg);

  881

  882     if (rpec != cpec) {

  883         pr_debug("i2c-core: Bad PEC 0x%02x vs. 0x%02x\n",

  884             rpec, cpec);

  885         return -1;

  886     }

  887     return 0;

  888 }

  889

  890 s32 i2c_smbus_write_quick(struct i2c_client *client, u8 value)

  891 {

  892     return i2c_smbus_xfer(client->adapter,client->addr,client->flags,

  893                           value,0,I2C_SMBUS_QUICK,NULL);

  894 }

  895

  896 s32 i2c_smbus_read_byte(struct i2c_client *client)

  897 {

  898     union i2c_smbus_data data;

  899     if (i2c_smbus_xfer(client->adapter,client->addr,client->flags,

  900                        I2C_SMBUS_READ,0,I2C_SMBUS_BYTE, &data))

  901         return -1;

  902     else

  903         return 0x0FF & data.byte;

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