Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <l4/cxx/unique_ptr>
- #include "main.h"
- //#include "irqs.h"
- #include "debug.h"
- #include "gpio"
- #include "hw_device.h"
- #include "hw_mmio_register_block.h"
- //#include "hw_irqs.h"
- #include "server.h"
- namespace {
- enum Regs : unsigned
- {
- // GPIO1_Base = 0x4a310000,
- // GPIO2_Base = 0x48055000,
- // GPIO3_Base = 0x48057000,
- // GPIO4_Base = 0x48059000,
- // GPIO5_Base = 0x4805B000,
- // GPIO6_Base = 0x4805D000,
- //Base = 0x00000000,
- Output_enable = 0x134,
- Irq_status0 = 0x02c,
- Irq_status_set = 0x034,
- Irq_status_clr = 0x03c,
- Ctrl = 0x130,
- Level_detect_low = 0x140,
- Level_detect_high = 0x144,
- Rising_detect = 0x148,
- Falling_detect = 0x14c,
- Clrdataout = 0x190,
- Setdataout = 0x194,
- Datain = 0x138,
- Dataout = 0x13c,
- DebounceEnable = 0x150,
- DebounceTime = 0x154,
- };
- template<typename T> static
- int getval(const char *s, cxx::String const &prop, Hw::Device::Prop_val const &val,
- T *rval)
- {
- if (prop == s)
- {
- if (val.type != Hw::Device::Prop_val::Int)
- return -Hw::Device::E_inval;
- *rval = val.val.integer;
- return Hw::Device::E_ok;
- }
- return -Hw::Device::E_no_prop;
- }
- class Gpio_omap44x_chip : public Hw::Gpio_device
- {
- private:
- Hw::Register_block<32> _regs;
- unsigned _nr_pins;
- //const unsigned *_scm_offset;
- //Gpio_irq_server *_irq_svr;
- //Scm_omap35x *_scm;
- enum Regs : unsigned
- {
- // GPIO1_Base = 0x4a310000,
- // GPIO2_Base = 0x48055000,
- // GPIO3_Base = 0x48057000,
- // GPIO4_Base = 0x48059000,
- // GPIO5_Base = 0x4805B000,
- // GPIO6_Base = 0x4805D000,
- //Base = 0x00000000,
- Revision = 0x000,
- Sysconfig = 0x010,
- Sysstatus = 0x114,
- Output_enable = 0x134,
- Irq_status0 = 0x02c,
- Irq_status_set = 0x034,
- Irq_status_clr = 0x03c,
- Ctrl = 0x130,
- Level_detect_low = 0x140,
- Level_detect_high = 0x144,
- Rising_detect = 0x148,
- Falling_detect = 0x14c,
- Clrdataout = 0x190,
- Setdataout = 0x194,
- Datain = 0x138,
- Dataout = 0x13c,
- DebounceEnable = 0x150,
- DebounceTime = 0x154,
- };
- enum Func : unsigned
- {
- Func_out = 0,
- Func_in = 1,
- };
- static l4_uint32_t _pin_bit(unsigned pin)
- { return 1 << (pin & 31); }
- static unsigned _pin_shift(unsigned pin)
- { return pin % 32; }
- //void config(unsigned pin, unsigned func)
- //{
- // if (_scm)
- // _scm->set_mode(_scm_offset[pin], func);
- //}
- public:
- Gpio_omap44x_chip() : _nr_pins(32)//, _scm_offset(0), _irq_svr(0), _scm(0)
- {
- add_cid("gpio");
- add_cid("gpio-omap44x");
- }
- unsigned nr_pins() const { return _nr_pins;}
- void request(unsigned) {}
- void free(unsigned) {}
- int get(unsigned pin);
- void set(unsigned pin, int value);
- void config_pad(unsigned pin, unsigned func, unsigned value);
- void config_get(unsigned pin, unsigned func, unsigned *value);
- void config_pull(unsigned pin, unsigned mode);
- void setup(unsigned pin, unsigned mode,int value=0); //This one to change direction. Not Implemented Yet
- void init();
- };
- int Gpio_omap44x_chip::get(unsigned pin)
- {
- if (pin>= _nr_pins)
- throw -L4_EINVAL;
- return (_regs[Dataout] >> _pin_shift(pin)) & 1;
- }
- void Gpio_omap44x_chip::set(unsigned pin, int value)
- {
- if(pin>=_nr_pins)
- throw -L4_EINVAL;
- unsigned reg_set = value ? Setdataout : Clrdataout;
- _regs[reg_set] = _pin_bit(pin);
- }
- void Gpio_omap44x_chip::config_pad(unsigned pin, unsigned reg, unsigned value)
- {
- if (pin >= _nr_pins)
- throw -L4_EINVAL;
- switch (reg)
- {
- case Output_enable:
- case Irq_status0:
- case Irq_status_set:
- case Level_detect_low:
- case Level_detect_high:
- case Rising_detect:
- case Falling_detect:
- case Clrdataout:
- case Setdataout:
- case Datain:
- case Dataout:
- case DebounceEnable:
- _regs[reg].modify(_pin_bit(pin), value ? _pin_bit(pin) : 0);
- default:
- // cannot allow the following registers, they have security implications
- // Sysconfig, Ctrl, Debouncing_time
- // the following registers are read-only
- // Revision, Sysstatus (also security), Data_in
- throw -L4_EINVAL;
- }
- }
- void Gpio_omap44x_chip::config_get(unsigned pin, unsigned reg, unsigned *value)
- {
- if(pin >= _nr_pins)
- throw -L4_EINVAL;
- switch(reg)
- {
- case Revision:
- *value = _regs[Revision] & 0xff;
- break;
- case Sysconfig:
- *value = _regs[Sysconfig] & 0xf;
- break;
- case Sysstatus:
- *value = _regs[Sysstatus] & 0x1;
- break;
- case Ctrl:
- *value = _regs[Ctrl] & 0x7;
- break;
- case DebounceTime:
- *value = _regs[DebounceTime] & 0xff;
- break;
- case Output_enable:
- case Irq_status0:
- case Irq_status_set:
- case Level_detect_low:
- case Level_detect_high:
- case Rising_detect:
- case Falling_detect:
- case Clrdataout:
- case Setdataout:
- case Datain:
- case Dataout:
- case DebounceEnable:
- *value = (_regs[reg] >> _pin_shift(pin)) & 1;
- break;
- default:
- throw -L4_EINVAL;
- }
- }
- void Gpio_omap44x_chip::config_pull(unsigned pin, unsigned mode)
- {
- if (pin >= _nr_pins)
- throw -L4_EINVAL;
- switch (mode)
- {
- case Pull_none:
- mode = 0;
- break;
- case Pull_up:
- mode = 3;
- break;
- case Pull_down:
- mode = 1;
- break;
- }
- //Lagi Lagi SCM
- // if (_scm)
- // _scm->set_pull(_scm_offset[pin], mode);
- }
- void Gpio_omap44x_chip::setup(unsigned pin, unsigned mode, int value)
- {
- if(pin>=_nr_pins)
- throw -L4_EINVAL;
- switch(mode)
- {
- case Input:
- _regs[Output_enable].set(_pin_bit(pin));
- //scm setting here. need more learn
- return;
- case Output:
- _regs[Output_enable].clear(_pin_bit(pin));
- //scm setting here. need more learn
- set(pin,value);
- return;
- default:
- mode &=0x7;
- break;
- }
- //Need SCM ~~~~
- //config(pin,mode);
- }
- void Gpio_omap44x_chip::init()
- {
- Gpio_device::init();
- Resource *regs = resources()->find("regs");
- if (!regs || regs->type() != Resource::Mmio_res)
- {
- d_printf(DBG_ERR, "error: %s: no base address set for device: Gpio_omap35x_chip\n"
- " missing or wrong 'regs' resource\n"
- " the chip will not work at all!\n", name());
- return;
- }
- l4_addr_t phys_base = regs->start();
- l4_addr_t size = regs->size();
- if (size < 0x100 || size > (1 << 12))
- {
- d_printf(DBG_ERR, "error: %s: invalid mmio size (%lx) for device: Gpio_omap44x_chip\n"
- " the chip will not work at all!\n", name(), size);
- return;
- }
- l4_addr_t vbase = res_map_iomem(phys_base, size);
- if (!vbase)
- {
- d_printf(DBG_ERR, "error: %s: cannot map registers for Gpio_omap44x_chip\n"
- " phys=%lx-%lx", name(),
- phys_base, phys_base + size - 1);
- return;
- }
- d_printf(DBG_DEBUG2, "%s: Gpio_omap44x_chip: mapped registers to %08lx\n",
- name(), vbase);
- _regs = new Hw::Mmio_register_block<32>(vbase);
- #pragma region IRQinit
- // Resource *irq = resources()->find("irq");
- // if (irq && irq->type() == Resource::Irq_res)
- // _irq_svr = new Gpio_irq_server(irq->start(), _nr_pins, vbase);
- // else
- // d_printf(DBG_WARN, "warning: %s: Gpio_omap35x_chip no irq configured\n", name());
- #pragma endregion IRQinit
- #pragma region SCMinit
- find Scm device
- for (auto i = Hw::Device::iterator(0, system_bus(), L4VBUS_MAX_DEPTH);
- i != Hw::Device::iterator(); ++i)
- // if ((*i)->match_cid("scm-omap35x"))
- // _scm = reinterpret_cast<Scm_omap35x *>(*i);
- // if (!_scm)
- // d_printf(DBG_WARN, "warning: %s: could not find Scm device for device: Gpio_omap35x_chip\n"
- // " Setting Gpio pin modes and PUD will be disabled\n", name());
- //}
- #pragma endregion SCMinit
- static Hw::Device_factory_t<Gpio_omap44x_chip> __hw_pf_factory("Gpio_omap44x_chip");
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement