Annotation of qemu/hw/smbus_eeprom.c, revision 1.1.1.7

1.1       root        1: /*
                      2:  * QEMU SMBus EEPROM device
1.1.1.2   root        3:  *
1.1       root        4:  * Copyright (c) 2007 Arastra, Inc.
1.1.1.2   root        5:  *
1.1       root        6:  * Permission is hereby granted, free of charge, to any person obtaining a copy
                      7:  * of this software and associated documentation files (the "Software"), to deal
                      8:  * in the Software without restriction, including without limitation the rights
                      9:  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
                     10:  * copies of the Software, and to permit persons to whom the Software is
                     11:  * furnished to do so, subject to the following conditions:
                     12:  *
                     13:  * The above copyright notice and this permission notice shall be included in
                     14:  * all copies or substantial portions of the Software.
                     15:  *
                     16:  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
                     17:  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
                     18:  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
                     19:  * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
                     20:  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
                     21:  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
                     22:  * THE SOFTWARE.
                     23:  */
                     24: 
1.1.1.2   root       25: #include "hw.h"
                     26: #include "i2c.h"
                     27: #include "smbus.h"
1.1       root       28: 
                     29: //#define DEBUG
                     30: 
                     31: typedef struct SMBusEEPROMDevice {
1.1.1.4   root       32:     SMBusDevice smbusdev;
1.1.1.5   root       33:     void *data;
1.1       root       34:     uint8_t offset;
                     35: } SMBusEEPROMDevice;
                     36: 
                     37: static void eeprom_quick_cmd(SMBusDevice *dev, uint8_t read)
                     38: {
                     39: #ifdef DEBUG
1.1.1.3   root       40:     printf("eeprom_quick_cmd: addr=0x%02x read=%d\n", dev->i2c.address, read);
1.1       root       41: #endif
                     42: }
                     43: 
                     44: static void eeprom_send_byte(SMBusDevice *dev, uint8_t val)
                     45: {
                     46:     SMBusEEPROMDevice *eeprom = (SMBusEEPROMDevice *) dev;
                     47: #ifdef DEBUG
1.1.1.3   root       48:     printf("eeprom_send_byte: addr=0x%02x val=0x%02x\n",
                     49:            dev->i2c.address, val);
1.1       root       50: #endif
                     51:     eeprom->offset = val;
                     52: }
                     53: 
                     54: static uint8_t eeprom_receive_byte(SMBusDevice *dev)
                     55: {
                     56:     SMBusEEPROMDevice *eeprom = (SMBusEEPROMDevice *) dev;
1.1.1.5   root       57:     uint8_t *data = eeprom->data;
                     58:     uint8_t val = data[eeprom->offset++];
1.1       root       59: #ifdef DEBUG
1.1.1.3   root       60:     printf("eeprom_receive_byte: addr=0x%02x val=0x%02x\n",
                     61:            dev->i2c.address, val);
1.1       root       62: #endif
                     63:     return val;
                     64: }
                     65: 
1.1.1.2   root       66: static void eeprom_write_data(SMBusDevice *dev, uint8_t cmd, uint8_t *buf, int len)
1.1       root       67: {
                     68:     SMBusEEPROMDevice *eeprom = (SMBusEEPROMDevice *) dev;
1.1.1.2   root       69:     int n;
1.1       root       70: #ifdef DEBUG
1.1.1.3   root       71:     printf("eeprom_write_byte: addr=0x%02x cmd=0x%02x val=0x%02x\n",
                     72:            dev->i2c.address, cmd, buf[0]);
1.1       root       73: #endif
1.1.1.2   root       74:     /* An page write operation is not a valid SMBus command.
                     75:        It is a block write without a length byte.  Fortunately we
                     76:        get the full block anyway.  */
                     77:     /* TODO: Should this set the current location?  */
                     78:     if (cmd + len > 256)
                     79:         n = 256 - cmd;
                     80:     else
                     81:         n = len;
                     82:     memcpy(eeprom->data + cmd, buf, n);
                     83:     len -= n;
                     84:     if (len)
                     85:         memcpy(eeprom->data, buf + n, len);
1.1       root       86: }
                     87: 
1.1.1.2   root       88: static uint8_t eeprom_read_data(SMBusDevice *dev, uint8_t cmd, int n)
1.1       root       89: {
                     90:     SMBusEEPROMDevice *eeprom = (SMBusEEPROMDevice *) dev;
1.1.1.2   root       91:     /* If this is the first byte then set the current position.  */
                     92:     if (n == 0)
                     93:         eeprom->offset = cmd;
                     94:     /* As with writes, we implement block reads without the
                     95:        SMBus length byte.  */
                     96:     return eeprom_receive_byte(dev);
1.1       root       97: }
                     98: 
1.1.1.6   root       99: static int smbus_eeprom_initfn(SMBusDevice *dev)
1.1       root      100: {
1.1.1.4   root      101:     SMBusEEPROMDevice *eeprom = (SMBusEEPROMDevice *)dev;
1.1.1.2   root      102: 
1.1       root      103:     eeprom->offset = 0;
1.1.1.5   root      104:     return 0;
1.1       root      105: }
1.1.1.4   root      106: 
                    107: static SMBusDeviceInfo smbus_eeprom_info = {
                    108:     .i2c.qdev.name = "smbus-eeprom",
                    109:     .i2c.qdev.size = sizeof(SMBusEEPROMDevice),
                    110:     .i2c.qdev.props = (Property[]) {
1.1.1.5   root      111:         DEFINE_PROP_PTR("data", SMBusEEPROMDevice, data),
                    112:         DEFINE_PROP_END_OF_LIST(),
1.1.1.4   root      113:     },
1.1.1.6   root      114:     .init = smbus_eeprom_initfn,
1.1.1.4   root      115:     .quick_cmd = eeprom_quick_cmd,
                    116:     .send_byte = eeprom_send_byte,
                    117:     .receive_byte = eeprom_receive_byte,
                    118:     .write_data = eeprom_write_data,
                    119:     .read_data = eeprom_read_data
                    120: };
                    121: 
                    122: static void smbus_eeprom_register_devices(void)
                    123: {
                    124:     smbus_register_device(&smbus_eeprom_info);
                    125: }
                    126: 
                    127: device_init(smbus_eeprom_register_devices)
1.1.1.6   root      128: 
                    129: void smbus_eeprom_init(i2c_bus *smbus, int nb_eeprom,
                    130:                        const uint8_t *eeprom_spd, int eeprom_spd_size)
                    131: {
                    132:     int i;
1.1.1.7 ! root      133:     uint8_t *eeprom_buf = g_malloc0(8 * 256); /* XXX: make this persistent */
1.1.1.6   root      134:     if (eeprom_spd_size > 0) {
                    135:         memcpy(eeprom_buf, eeprom_spd, eeprom_spd_size);
                    136:     }
                    137: 
                    138:     for (i = 0; i < nb_eeprom; i++) {
                    139:         DeviceState *eeprom;
                    140:         eeprom = qdev_create((BusState *)smbus, "smbus-eeprom");
                    141:         qdev_prop_set_uint8(eeprom, "address", 0x50 + i);
                    142:         qdev_prop_set_ptr(eeprom, "data", eeprom_buf + (i * 256));
                    143:         qdev_init_nofail(eeprom);
                    144:     }
                    145: }

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.