Advertisement
errypuu

omap44x2.cc

Dec 29th, 2014
68
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 7.77 KB | None | 0 0
  1. #include <l4/cxx/unique_ptr>
  2.  
  3. #include "main.h"
  4. //#include "irqs.h"
  5. #include "debug.h"
  6. #include "gpio"
  7. #include "hw_device.h"
  8. #include "hw_mmio_register_block.h"
  9. //#include "hw_irqs.h"
  10. #include "server.h"
  11.  
  12. namespace {
  13.  
  14.     enum Regs : unsigned
  15.     {
  16.         //  GPIO1_Base          = 0x4a310000,
  17.         //  GPIO2_Base          = 0x48055000,
  18.         //  GPIO3_Base          = 0x48057000,
  19.         //  GPIO4_Base          = 0x48059000,
  20.         //  GPIO5_Base          = 0x4805B000,
  21.         //  GPIO6_Base          = 0x4805D000,
  22.  
  23.         //Base              = 0x00000000,
  24.         Output_enable       = 0x134,
  25.         Irq_status0         = 0x02c,
  26.         Irq_status_set      = 0x034,
  27.         Irq_status_clr      = 0x03c,
  28.         Ctrl                = 0x130,
  29.         Level_detect_low    = 0x140,
  30.         Level_detect_high   = 0x144,
  31.         Rising_detect       = 0x148,
  32.         Falling_detect      = 0x14c,
  33.         Clrdataout          = 0x190,
  34.         Setdataout          = 0x194,
  35.         Datain              = 0x138,
  36.         Dataout             = 0x13c,
  37.         DebounceEnable      = 0x150,
  38.         DebounceTime        = 0x154,
  39.     };
  40.  
  41.     template<typename T> static
  42.         int getval(const char *s, cxx::String const &prop, Hw::Device::Prop_val const &val,
  43.         T *rval)
  44.     {
  45.         if (prop == s)
  46.         {
  47.             if (val.type != Hw::Device::Prop_val::Int)
  48.                 return -Hw::Device::E_inval;
  49.  
  50.             *rval = val.val.integer;
  51.             return Hw::Device::E_ok;
  52.         }
  53.         return -Hw::Device::E_no_prop;
  54.     }
  55.  
  56.     class Gpio_omap44x_chip : public Hw::Gpio_device
  57.     {
  58.     private:
  59.         Hw::Register_block<32> _regs;
  60.         unsigned _nr_pins;
  61.         //const unsigned *_scm_offset;
  62.         //Gpio_irq_server *_irq_svr;
  63.         //Scm_omap35x *_scm;
  64.         enum Regs : unsigned
  65.         {
  66.             //  GPIO1_Base          = 0x4a310000,
  67.             //  GPIO2_Base          = 0x48055000,
  68.             //  GPIO3_Base          = 0x48057000,
  69.             //  GPIO4_Base          = 0x48059000,
  70.             //  GPIO5_Base          = 0x4805B000,
  71.             //  GPIO6_Base          = 0x4805D000,
  72.  
  73.             //Base              = 0x00000000,
  74.             Revision            = 0x000,
  75.             Sysconfig           = 0x010,
  76.             Sysstatus           = 0x114,
  77.             Output_enable       = 0x134,
  78.             Irq_status0         = 0x02c,
  79.             Irq_status_set      = 0x034,
  80.             Irq_status_clr      = 0x03c,
  81.             Ctrl                = 0x130,
  82.             Level_detect_low    = 0x140,
  83.             Level_detect_high   = 0x144,
  84.             Rising_detect       = 0x148,
  85.             Falling_detect      = 0x14c,
  86.             Clrdataout          = 0x190,
  87.             Setdataout          = 0x194,
  88.             Datain              = 0x138,
  89.             Dataout             = 0x13c,
  90.             DebounceEnable      = 0x150,
  91.             DebounceTime        = 0x154,
  92.         };
  93.  
  94.         enum Func : unsigned
  95.         {
  96.             Func_out = 0,
  97.             Func_in  = 1,
  98.         };
  99.         static l4_uint32_t _pin_bit(unsigned pin)
  100.         { return 1 << (pin & 31); }
  101.  
  102.         static unsigned _pin_shift(unsigned pin)
  103.         { return pin % 32; }
  104.  
  105.         //void config(unsigned pin, unsigned func)
  106.         //{
  107.         //  if (_scm)
  108.         //      _scm->set_mode(_scm_offset[pin], func);
  109.         //}
  110.  
  111.  
  112.     public:
  113.         Gpio_omap44x_chip() : _nr_pins(32)//, _scm_offset(0), _irq_svr(0), _scm(0)
  114.         {
  115.             add_cid("gpio");
  116.             add_cid("gpio-omap44x");
  117.         }
  118.  
  119.         unsigned nr_pins() const { return _nr_pins;}
  120.         void request(unsigned) {}
  121.         void free(unsigned) {}
  122.         int get(unsigned pin);
  123.         void set(unsigned pin, int value);
  124.         void config_pad(unsigned pin, unsigned func, unsigned value);
  125.         void config_get(unsigned pin, unsigned func, unsigned *value);
  126.         void config_pull(unsigned pin, unsigned mode);
  127.         void setup(unsigned pin, unsigned mode,int value=0); //This one to change direction. Not Implemented Yet   
  128.  
  129.         void init();
  130.     };
  131.  
  132.     int Gpio_omap44x_chip::get(unsigned pin)
  133.     {
  134.         if (pin>= _nr_pins)
  135.             throw -L4_EINVAL;
  136.  
  137.         return (_regs[Dataout] >> _pin_shift(pin)) & 1;
  138.     }
  139.  
  140.     void Gpio_omap44x_chip::set(unsigned pin, int value)
  141.     {
  142.         if(pin>=_nr_pins)
  143.             throw -L4_EINVAL;
  144.  
  145.         unsigned reg_set = value ? Setdataout : Clrdataout;
  146.         _regs[reg_set] = _pin_bit(pin);
  147.     }
  148.  
  149.     void Gpio_omap44x_chip::config_pad(unsigned pin, unsigned reg, unsigned value)
  150.     {
  151.         if (pin >= _nr_pins)
  152.             throw -L4_EINVAL;
  153.  
  154.         switch (reg)
  155.         {
  156.         case Output_enable:
  157.         case Irq_status0:
  158.         case Irq_status_set:
  159.         case Level_detect_low:
  160.         case Level_detect_high:
  161.         case Rising_detect:
  162.         case Falling_detect:
  163.         case Clrdataout:
  164.         case Setdataout:
  165.         case Datain:
  166.         case Dataout:
  167.         case DebounceEnable:
  168.             _regs[reg].modify(_pin_bit(pin), value ? _pin_bit(pin) : 0);
  169.  
  170.         default:
  171.             // cannot allow the following registers, they have security implications
  172.             // Sysconfig, Ctrl, Debouncing_time
  173.             // the following registers are read-only
  174.             // Revision, Sysstatus (also security), Data_in
  175.             throw -L4_EINVAL;
  176.         }
  177.     }
  178.  
  179.     void Gpio_omap44x_chip::config_get(unsigned pin, unsigned reg, unsigned *value)
  180.     {
  181.         if(pin >= _nr_pins)
  182.             throw -L4_EINVAL;
  183.  
  184.         switch(reg)
  185.         {
  186.         case Revision:
  187.             *value = _regs[Revision] & 0xff;
  188.             break;
  189.         case Sysconfig:
  190.             *value = _regs[Sysconfig] & 0xf;
  191.             break;
  192.         case Sysstatus:
  193.             *value = _regs[Sysstatus] & 0x1;
  194.             break;
  195.         case Ctrl:
  196.             *value = _regs[Ctrl] & 0x7;
  197.             break;
  198.         case DebounceTime:
  199.             *value = _regs[DebounceTime] & 0xff;
  200.             break;
  201.         case Output_enable:
  202.         case Irq_status0:
  203.         case Irq_status_set:
  204.         case Level_detect_low:
  205.         case Level_detect_high:
  206.         case Rising_detect:
  207.         case Falling_detect:
  208.         case Clrdataout:
  209.         case Setdataout:
  210.         case Datain:
  211.         case Dataout:
  212.         case DebounceEnable:
  213.             *value = (_regs[reg] >> _pin_shift(pin)) & 1;
  214.             break;
  215.  
  216.         default:
  217.             throw -L4_EINVAL;
  218.         }
  219.     }
  220.  
  221.     void Gpio_omap44x_chip::config_pull(unsigned pin, unsigned mode)
  222.     {
  223.         if (pin >= _nr_pins)
  224.             throw -L4_EINVAL;
  225.  
  226.         switch (mode)
  227.         {
  228.         case Pull_none:
  229.             mode = 0;
  230.             break;
  231.         case Pull_up:
  232.             mode = 3;
  233.             break;
  234.         case Pull_down:
  235.             mode = 1;
  236.             break;
  237.         }
  238.  
  239.         //Lagi Lagi SCM
  240.         // if (_scm)
  241.         //  _scm->set_pull(_scm_offset[pin], mode);
  242.     }
  243.  
  244.  
  245.     void Gpio_omap44x_chip::setup(unsigned pin, unsigned mode, int value)
  246.     {
  247.         if(pin>=_nr_pins)
  248.             throw -L4_EINVAL;
  249.  
  250.         switch(mode)
  251.         {
  252.         case Input:
  253.             _regs[Output_enable].set(_pin_bit(pin));
  254.             //scm setting here. need more learn
  255.             return;
  256.         case Output:
  257.             _regs[Output_enable].clear(_pin_bit(pin));
  258.             //scm setting here. need more learn
  259.             set(pin,value);
  260.             return;
  261.         default:
  262.             mode &=0x7;
  263.             break;
  264.         }
  265.         //Need SCM ~~~~
  266.         //config(pin,mode);
  267.     }
  268.  
  269.     void Gpio_omap44x_chip::init()
  270.     {
  271.         Gpio_device::init();
  272.  
  273.         Resource *regs = resources()->find("regs");
  274.         if (!regs || regs->type() != Resource::Mmio_res)
  275.         {
  276.             d_printf(DBG_ERR, "error: %s: no base address set for device: Gpio_omap35x_chip\n"
  277.                 "       missing or wrong 'regs' resource\n"
  278.                 "       the chip will not work at all!\n", name());
  279.             return;
  280.         }
  281.  
  282.         l4_addr_t phys_base = regs->start();
  283.         l4_addr_t size = regs->size();
  284.  
  285.         if (size < 0x100 || size > (1 << 12))
  286.         {
  287.             d_printf(DBG_ERR, "error: %s: invalid mmio size (%lx) for device: Gpio_omap44x_chip\n"
  288.                 "       the chip will not work at all!\n", name(), size);
  289.             return;
  290.         }
  291.  
  292.         l4_addr_t vbase = res_map_iomem(phys_base, size);
  293.         if (!vbase)
  294.         {
  295.             d_printf(DBG_ERR, "error: %s: cannot map registers for Gpio_omap44x_chip\n"
  296.                 "       phys=%lx-%lx", name(),
  297.                 phys_base, phys_base + size - 1);
  298.             return;
  299.         }
  300.  
  301.         d_printf(DBG_DEBUG2, "%s: Gpio_omap44x_chip: mapped registers to %08lx\n",
  302.             name(), vbase);
  303.  
  304.         _regs = new Hw::Mmio_register_block<32>(vbase);
  305.  
  306. #pragma region IRQinit
  307.         //      Resource *irq = resources()->find("irq");
  308.         //  if (irq && irq->type() == Resource::Irq_res)
  309.         //      _irq_svr = new Gpio_irq_server(irq->start(), _nr_pins, vbase);
  310.         //  else
  311.         //  d_printf(DBG_WARN, "warning: %s: Gpio_omap35x_chip no irq configured\n", name());
  312. #pragma endregion IRQinit
  313.  
  314. #pragma region SCMinit
  315.          find Scm device
  316.          for (auto i = Hw::Device::iterator(0, system_bus(), L4VBUS_MAX_DEPTH);
  317.          i != Hw::Device::iterator(); ++i)
  318.         // if ((*i)->match_cid("scm-omap35x"))
  319.         //  _scm = reinterpret_cast<Scm_omap35x *>(*i);
  320.         //        if (!_scm)
  321.         //        d_printf(DBG_WARN, "warning: %s: could not find Scm device for device: Gpio_omap35x_chip\n"
  322.         //       "         Setting Gpio pin modes and PUD will be disabled\n", name());
  323.         //}
  324. #pragma endregion SCMinit
  325.  
  326.         static Hw::Device_factory_t<Gpio_omap44x_chip> __hw_pf_factory("Gpio_omap44x_chip");
  327.     }
  328. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement