On Tue, 2012-10-16 at 11:34 +0100, Ian Campbell wrote:
> I'm AFK this weekend but I'll see if I can prototype something soon.

Took a bit longer than expected but I've been playing with consolidating
the various configuration files into a single one which automatically
detects and enables the various hardware features.

Please can you try installing the attached consolidated.lua
as /etc/qcontrol.conf and see if it does what you expect wrt the LCD
(and more generally)?

I'm not 100% sold on this approach, since the consolidated file is a
fair bit more complex than the separate ones, but on the other hand
there is far less duplication.

Even if I don't ultimately decide to take this approach the code to
select things based on the value of a GPIO would still be useful, since
I would add it to ts41x.lua.

Ian.
--[[
Debian configuration file for qcontrol (LUA syntax)
Supports the following devices:
   - TS-109
   - TS-209
   - TS-119
   - TS-219
   - TS-409
   - TS-41x
}
--]]

-- Useful for testing
--function logprint(arg)
--   print(arg)
--
--function register(mod, ...)
--   args = ...
--   logprint(model..": register module "..mod)
--   if args then logprint(model..": extra params "..args) end
--end


-- If argument is a function then call it, else return it.
function evalfn(f)
   if type(f) == "function" then
      return f(  )
   else
      return f
   end
end

-- Select a value based on the state of a GPIO pin.
--
-- results == list of result to return for each state
-- value=1       => results[1]
-- value=0       => results[2]
-- value unknown => results[3]
--
-- If result is a function it will be called
function gpio_select(number, results)
   local path=string.format("/sys/class/gpio/gpio%d/value", number)
   local gpio=io.open(path)
   if not gpio then
      logprint(string.format("%s does not exist, trying to enable", path))
      g = io.open("/sys/class/gpio/enable")
      if not g then
         logprint("unable to open gpio control file")
         return evalfn(results[3])
      end
      g:write(number)
      gpio=io.open(path)
   end
   if not gpio then
      logprint("unable to open gpio file")
      return evalfn(results[3])
   end
   
   local v=gpio:read("*n")
   
   if v == 1     then return evalfn(results[1])
   elseif v == 0 then return evalfn(results[2])
   else               return evalfn(results[3])
   end
end

-- Returns a function which selects on a GPIO. i.e. defers the test
-- until it is called.
function gpio(number, results)
   return function() return gpio_select(number, results) end
end

-- List of supported hardware. Key is the "Hardware" tag from
-- /proc/cpuinfo.
--
-- Each entry is a selecton of keys. If a key is a function it will be
-- executed.
--
-- keys:
-- -- model:               selects the model name
-- -- ram:                 selects the amount of RAM
-- -- module:              the hardware support module to load 
-- -- lcd:                 selects for and registers the LCD module
-- -- advance_fan_control: boolean
supported_hardware = {
   ["QNAP TS-109/TS-209"] = {
      model = "ts109/209",
      module = "ts209",
      advanced_fan_control = false,
   },
   ["QNAP TS-119/TS-219"] = {
      model = gpio(44, {"ts21x", "ts11x", "Unknown model"}),
      ram =   gpio(36, {"512", "256", "Unknown"}),
      module = "ts219",
      advanced_fan_control = true,
   },
   ["QNAP TS-409"] = {
      model="ts409",
      module = "ts409",
      advanced_fan_control = true,
   },
   ["QNAP TS-41x"] = {
      model = gpio(44, {"ts419", "ts419u", "Unknown model"}),
      ram = gpio_select(36, {"512", "256", "Unknown"}),
      module = "ts41x",
      advanced_fan_control = true,
      lcd = gpio(45, {nil,
                      function () register("a125", "/dev/ttyS0") end,
                      nil}),
   },
   -- Used if hardware cannot be detected
   ["<unknown>"] = {
      model = "unknown",
   }
}

for line in io.lines("/proc/cpuinfo") do
   hardware = line:match("Hardware%s*: (.*)") 
   if hardware then break end
end
if not hardware then
   logprint("Failed to read hardware from cpuinfo")
   hardware = "<unknown>"
end

hw = supported_hardware[hardware]
if not hw then
   logprint("Unknown hardware type.")
   hw = supported_hardware["unknown"]
end

model = evalfn(hw.model)

logprint(model..": Initialising (cpuinfo: "..hardware..")")

ram = evalfn(hw.ram)

if ram then logprint(model..": "..ram.."MB RAM detected") end

if hw.module then register(hw.module) end

-- Enable hardware support based on hw.

-- Requires CONFIG_KEYBOARD_GPIO enabled in the kernel and
-- the kernel module gpio_keys to be loaded.
register("evdev", "/dev/input/by-path/platform-gpio-keys-event",
        408, "restart_button",
        133, "media_button")

function power_button( time )
        os.execute("poweroff")
end

function restart_button( time )
        os.execute("reboot")
end

function media_button( time )
        piccmd("usbled", "8hz")
end

fanfail = 0

function fan_error(  )
   fanfail = fanfail + 1
   if fanfail == 3 then
      logprint(model..": fan error")
      piccmd("statusled", "red2hz")
      piccmd("buzzer", "long")
   else
      if fanfail == 10 then fanfail = 0 end
   end
end

function fan_normal(  )
   piccmd("statusled", "greenon")
   fanfail = 0
end

last_temp_log = nil
last_temp_value = 0

function logtemp( temp )
   now = os.time()
   -- Log only every 5 minutes or if the temperature has changed by
   -- more than 5.
   if ( ( not last_temp_log ) or
     ( os.difftime(now, last_temp_log) >= 300 ) or
  ( math.abs( temp - last_temp_value ) >= 5 ) ) then
      logprint(model..": temperature "..temp)
      last_temp_log = now
      last_temp_value = temp
   end
end

last_fan_setting = nil

function setfan( speed )
   if ( ( not last_fan_setting ) or
     ( last_fan_setting ~= speed ) ) then
      logprint(model..": setting fan to \""..speed.."\"")
   end
   piccmd("fanspeed", speed)
   last_fan_setting = speed
end

if hw.advanced_fan_control ~= nil then
   if hw.advanced_fan_control then
      logprint(model..": enable advanced fan control")
      function temp( temp )
         logtemp(temp)
         if temp > 80 then     setfan("full")
         elseif temp > 70 then setfan("high")
         elseif temp > 55 then setfan("medium")
         elseif temp > 30 then setfan("low")
         else                  setfan("silence")
         end
      end
   else
      logprint(model..": enable basic fan control")
      function temp_low(  )
         setfan("silence")
      end
      
      function temp_high(  )
         setfan("full")
      end
   end
else
   logprint(model..": no fan control")
end

if hw.lcd then
   logprint(model..": enable LCD")
   evalfn(hw.lcd)

   function lcd_button( state, down, up )
      -- exactly key 1 and 2 pressed switches backlight off
      if state == 3 then
	 piccmd("lcd-backlight", "off")
      else
	 -- any key pressed activates the backlight
	 if down ~= 0 then
	    piccmd("lcd-backlight", "on")
	 end
	 -- pressing key 1 switches off the usbled the media-key enables...
	 if down == 1 then
	    piccmd("usbled", "off")
	 end
      end
   end
end

Attachment: signature.asc
Description: This is a digitally signed message part

Reply via email to