110800SN/A/*
210800SN/A * Copyright (c) 2012 ARM Limited
310800SN/A * All rights reserved
410800SN/A *
510800SN/A * The license below extends only to copyright in the software and shall
610800SN/A * not be construed as granting a license to any other intellectual
710800SN/A * property including but not limited to intellectual property relating
810800SN/A * to a hardware implementation of the functionality of the software
910800SN/A * licensed hereunder.  You may use the software subject to the license
1010800SN/A * terms below provided that you ensure that this notice is replicated
1110800SN/A * unmodified and in its entirety in all distributions of the software,
1210800SN/A * modified or unmodified, in source code or in binary form.
1310800SN/A *
1410800SN/A * Redistribution and use in source and binary forms, with or without
1510800SN/A * modification, are permitted provided that the following conditions are
1610800SN/A * met: redistributions of source code must retain the above copyright
1710800SN/A * notice, this list of conditions and the following disclaimer;
1810800SN/A * redistributions in binary form must reproduce the above copyright
1910800SN/A * notice, this list of conditions and the following disclaimer in the
2010800SN/A * documentation and/or other materials provided with the distribution;
2110800SN/A * neither the name of the copyright holders nor the names of its
2210800SN/A * contributors may be used to endorse or promote products derived from
2310800SN/A * this software without specific prior written permission.
2410800SN/A *
2510800SN/A * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
2610800SN/A * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
2710800SN/A * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
2810800SN/A * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
2910800SN/A * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
3010800SN/A * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
3110800SN/A * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
3210800SN/A * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
3310800SN/A * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
3410800SN/A * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
3510800SN/A * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
3610800SN/A *
3710800SN/A * Authors: Peter Enns
3810800SN/A */
3910800SN/A
4010800SN/A
4110800SN/A/** @file
4210800SN/A * Implementiation of an i2c bus
4310800SN/A */
4410800SN/A
4511262Sandreas.sandberg@arm.com#ifndef __DEV_I2C_BUS_HH__
4611262Sandreas.sandberg@arm.com#define __DEV_I2C_BUS_HH__
4710800SN/A
4810800SN/A#include <map>
4910800SN/A
5010800SN/A#include "dev/io_device.hh"
5110800SN/A#include "params/I2CBus.hh"
5210800SN/A
5311262Sandreas.sandberg@arm.comclass I2CDevice;
5411262Sandreas.sandberg@arm.com
5510800SN/Aclass I2CBus : public BasicPioDevice
5610800SN/A{
5710800SN/A  protected:
5810800SN/A
5910800SN/A    enum I2CState {
6010800SN/A        IDLE,
6110800SN/A        RECEIVING_ADDR,
6210800SN/A        RECEIVING_DATA,
6310800SN/A        SENDING_DATA,
6410800SN/A    };
6510800SN/A
6610800SN/A    /**
6710800SN/A     * Read [and Set] serial control bits:
6810800SN/A     * Bit [0] is SCL
6910800SN/A     * Bit [1] is SDA
7010800SN/A     *
7110800SN/A     * http://infocenter.arm.com/help/topic/com.arm.doc.dui0440b/Bbajdjeg.html
7210800SN/A     */
7310800SN/A    static const int SB_CONTROLS = 0x0;
7410800SN/A    /** Clear control bits. Analogous to SB_CONTROLS */
7510800SN/A    static const int SB_CONTROLC = 0x4;
7610800SN/A
7710800SN/A    /** I2C clock wire (0, 1). */
7810800SN/A    uint8_t scl;
7910800SN/A    /** I2C data wire (0, 1) */
8010800SN/A    uint8_t sda;
8110800SN/A
8210800SN/A    /**
8310800SN/A     * State used by I2CBus::write to determine what stage of an i2c
8410800SN/A     * transmission it is currently in.
8510800SN/A     */
8610800SN/A    enum I2CState state;
8710800SN/A
8810800SN/A    /**
8910800SN/A     * Order of the bit of the current message that is being sent or
9010800SN/A     * received (0 - 7).
9110800SN/A     */
9210800SN/A    int currBit;
9310800SN/A
9410800SN/A    /**
9510800SN/A     * Key used to access a device in the slave devices map. This
9610800SN/A     * is the same address that is specified in kernel board
9710800SN/A     * initialization code (e.g., arch/arm/mach-realview/core.c).
9810800SN/A     */
9910800SN/A    uint8_t i2cAddr;
10010800SN/A
10110800SN/A    /** 8-bit buffer used to send and receive messages bit by bit. */
10210800SN/A    uint8_t message;
10310800SN/A
10410800SN/A    /**
10510800SN/A     * All the slave i2c devices that are connected to this
10610800SN/A     * bus. Each device has an address that points to the actual
10710800SN/A     * device.
10810800SN/A     */
10910800SN/A    std::map<uint8_t, I2CDevice*> devices;
11010800SN/A
11110800SN/A    /**
11210800SN/A     * Update data (sda) and clock (scl) to match any transitions
11310800SN/A     * specified by pkt.
11410800SN/A     *
11510800SN/A     * @param pkt memory request packet
11610800SN/A     */
11710800SN/A    void updateSignals(PacketPtr pkt);
11810800SN/A
11910800SN/A    /**
12010800SN/A     * Clock set check
12110800SN/A     *
12210800SN/A     * @param pkt memory request packet
12310800SN/A     * @return true if pkt indicates that scl transition from 0 to 1
12410800SN/A     */
12510800SN/A    bool isClockSet(PacketPtr pkt) const;
12610800SN/A
12710800SN/A    /**
12810800SN/A     * i2c start signal check
12910800SN/A     *
13010800SN/A     * @param pkt memory request packet
13110800SN/A     * @return true if pkt indicates a new transmission
13210800SN/A     */
13310800SN/A    bool isStart(PacketPtr pkt) const;
13410800SN/A
13510800SN/A    /**
13610800SN/A     * i2c end signal check
13710800SN/A     *
13810800SN/A     * @param pkt memory request packet
13910800SN/A     * @return true if pkt indicates stopping the current transmission
14010800SN/A     */
14110800SN/A    bool isEnd(PacketPtr pkt) const;
14210800SN/A
14310800SN/A  public:
14410800SN/A
14510800SN/A    I2CBus(const I2CBusParams* p);
14610800SN/A
14711169SN/A    Tick read(PacketPtr pkt) override;
14811169SN/A    Tick write(PacketPtr pkt) override;
14910800SN/A
15011168SN/A    void serialize(CheckpointOut &cp) const override;
15111168SN/A    void unserialize(CheckpointIn &cp) override;
15210800SN/A};
15310800SN/A
15411262Sandreas.sandberg@arm.com#endif // __DEV_I2C_BUS_HH__
155