Kindle: toggle cover events

Allow disabling the hall efect sensor via the sysfs knob, so the kindle system wont sleep & wake the device

for those of use that stay in koreader, are caseless and have get spurious wakeups
reviewable/pr10389/r1
yparitcher 1 year ago committed by GitHub
parent 4f23a6fafa
commit 1102c030fa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -726,6 +726,7 @@ function KindlePaperWhite2:init()
fl_intensity_file = "/sys/class/backlight/max77696-bl/brightness",
batt_capacity_file = "/sys/devices/system/wario_battery/wario_battery0/battery_capacity",
is_charging_file = "/sys/devices/system/wario_charger/wario_charger0/charging",
hall_file = "/sys/devices/system/wario_hall/wario_hall0/hall_enable",
}
Kindle.init(self)
@ -740,6 +741,7 @@ function KindleBasic:init()
device = self,
batt_capacity_file = "/sys/devices/system/wario_battery/wario_battery0/battery_capacity",
is_charging_file = "/sys/devices/system/wario_charger/wario_charger0/charging",
hall_file = "/sys/devices/system/wario_hall/wario_hall0/hall_enable",
}
Kindle.init(self)
@ -755,6 +757,7 @@ function KindleVoyage:init()
fl_intensity_file = "/sys/class/backlight/max77696-bl/brightness",
batt_capacity_file = "/sys/devices/system/wario_battery/wario_battery0/battery_capacity",
is_charging_file = "/sys/devices/system/wario_charger/wario_charger0/charging",
hall_file = "/sys/devices/system/wario_hall/wario_hall0/hall_enable",
}
self.input = require("device/input"):new{
device = self,
@ -814,6 +817,7 @@ function KindlePaperWhite3:init()
fl_intensity_file = "/sys/class/backlight/max77696-bl/brightness",
batt_capacity_file = "/sys/devices/system/wario_battery/wario_battery0/battery_capacity",
is_charging_file = "/sys/devices/system/wario_charger/wario_charger0/charging",
hall_file = "/sys/devices/system/wario_hall/wario_hall0/hall_enable",
}
Kindle.init(self)
@ -870,6 +874,7 @@ function KindleOasis:init()
-- NOTE: Points to the embedded battery. The one in the cover is codenamed "soda".
batt_capacity_file = "/sys/devices/system/wario_battery/wario_battery0/battery_capacity",
is_charging_file = "/sys/devices/system/wario_charger/wario_charger0/charging",
hall_file = "/sys/devices/system/wario_hall/wario_hall0/hall_enable",
}
self.input = require("device/input"):new{
@ -1130,6 +1135,7 @@ function KindleBasic2:init()
batt_capacity_file = "/sys/class/power_supply/bd7181x_bat/capacity",
is_charging_file = "/sys/class/power_supply/bd7181x_bat/charging",
batt_status_file = "/sys/class/power_supply/bd7181x_bat/status",
hall_file = "/sys/devices/system/heisenberg_hall/heisenberg_hall0/hall_enable",
}
Kindle.init(self)
@ -1146,6 +1152,7 @@ function KindlePaperWhite4:init()
batt_capacity_file = "/sys/class/power_supply/bd71827_bat/capacity",
is_charging_file = "/sys/class/power_supply/bd71827_bat/charging",
batt_status_file = "/sys/class/power_supply/bd71827_bat/status",
hall_file = "/sys/bus/platform/drivers/hall_sensor/rex_hall/hall_enable",
}
Kindle.init(self)
@ -1172,6 +1179,7 @@ function KindleBasic3:init()
batt_capacity_file = "/sys/class/power_supply/bd71827_bat/capacity",
is_charging_file = "/sys/class/power_supply/bd71827_bat/charging",
batt_status_file = "/sys/class/power_supply/bd71827_bat/status",
hall_file = "/sys/bus/platform/drivers/hall_sensor/rex_hall/hall_enable",
}
Kindle.init(self)
@ -1193,6 +1201,7 @@ function KindlePaperWhite5:init()
batt_capacity_file = "/sys/class/power_supply/bd71827_bat/capacity",
is_charging_file = "/sys/class/power_supply/bd71827_bat/charging",
batt_status_file = "/sys/class/power_supply/bd71827_bat/status",
hall_file = "/sys/devices/platform/eink_hall/hall_enable",
}
-- Enable the so-called "fast" mode, so as to prevent the driver from silently promoting refreshes to REAGL.

@ -1,6 +1,7 @@
local BasePowerD = require("device/generic/powerd")
local WakeupMgr = require("device/wakeupmgr")
local logger = require("logger")
local util = require("util")
-- liblipclua, see require below
local KindlePowerD = BasePowerD:new{
@ -98,11 +99,12 @@ function KindlePowerD:setIntensityHW(intensity)
-- NOTE: when intensity is 0, we want to *really* kill the light, so do it manually
-- (asking lipc to set it to 0 would in fact set it to > 0 on ! canTurnFrontlightOff Kindles).
-- We do *both* to make the fl restore on resume less jarring on devices where lipc 0 != off.
os.execute("printf '%s' ".. intensity .." > " .. self.fl_intensity_file)
util.writeToSysfs(intensity, self.fl_intensity_file)
-- And in case there are two LED groups...
-- This should never happen as all warmth devices so far canTurnFrontlightOff
if self.warmth_intensity_file then
os.execute("printf '%s' ".. intensity .." > " .. self.warmth_intensity_file)
util.writeToSysfs(intensity, self.warmth_intensity_file)
end
end
end
@ -161,6 +163,20 @@ function KindlePowerD:isChargedHW()
return false
end
function KindlePowerD:hasHallSensor()
return self.hall_file ~= nil
end
function KindlePowerD:isHallSensorEnabled()
local int = self:read_int_file(self.hall_file)
return int == 1
end
function KindlePowerD:onToggleHallSensor()
local stat = self:isHallSensorEnabled()
util.writeToSysfs(stat and 0 or 1, self.hall_file)
end
function KindlePowerD:_readFLIntensity()
return self:read_int_file(self.fl_intensity_file)
end

@ -47,25 +47,6 @@ local function checkStandby()
return no
end
local function writeToSys(val, file)
-- NOTE: We do things by hand via ffi, because io.write uses fwrite,
-- which isn't a great fit for procfs/sysfs (e.g., we lose failure cases like EBUSY,
-- as it only reports failures to write to the *stream*, not to the disk/file!).
local fd = C.open(file, bit.bor(C.O_WRONLY, C.O_CLOEXEC)) -- procfs/sysfs, we shouldn't need O_TRUNC
if fd == -1 then
logger.err("Cannot open file `" .. file .. "`:", ffi.string(C.strerror(ffi.errno())))
return
end
local bytes = #val
local nw = C.write(fd, val, bytes)
if nw == -1 then
logger.err("Cannot write `" .. val .. "` to file `" .. file .. "`:", ffi.string(C.strerror(ffi.errno())))
end
C.close(fd)
-- NOTE: Allows the caller to possibly handle short writes (not that these should ever happen here).
return nw == bytes
end
-- Return the highest core number
local function getCPUCount()
local fd = io.open("/sys/devices/system/cpu/possible", "re")
@ -1064,7 +1045,7 @@ function Kobo:standby(max_duration)
logger.dbg("Kobo standby: asking to enter standby . . .")
local standby_time = time.boottime_or_realtime_coarse()
local ret = writeToSys("standby", "/sys/power/state")
local ret = util.writeToSysfs("standby", "/sys/power/state")
self.last_standby_time = time.boottime_or_realtime_coarse() - standby_time
self.total_standby_time = self.total_standby_time + self.last_standby_time
@ -1140,7 +1121,7 @@ function Kobo:suspend()
-- NOTE: Sets gSleep_Mode_Suspend to 1. Used as a flag throughout the
-- kernel to suspend/resume various subsystems
-- c.f., state_extended_store @ kernel/power/main.c
local ret = writeToSys("1", "/sys/power/state-extended")
local ret = util.writeToSysfs("1", "/sys/power/state-extended")
if ret then
logger.dbg("Kobo suspend: successfully asked the kernel to put subsystems to sleep")
else
@ -1174,7 +1155,7 @@ function Kobo:suspend()
logger.dbg("Kobo suspend: asking for a suspend to RAM . . .")
local suspend_time = time.boottime_or_realtime_coarse()
ret = writeToSys("mem", "/sys/power/state")
ret = util.writeToSysfs("mem", "/sys/power/state")
-- NOTE: At this point, we *should* be in suspend to RAM, as such,
-- execution should only resume on wakeup...
@ -1189,7 +1170,7 @@ function Kobo:suspend()
else
logger.warn("Kobo suspend: the kernel refused to enter suspend!")
-- Reset state-extended back to 0 since we are giving up.
writeToSys("0", "/sys/power/state-extended")
util.writeToSysfs("0", "/sys/power/state-extended")
if G_reader_settings:isTrue("pm_debug_entry_failure") then
self:toggleChargingLED(true)
end
@ -1238,7 +1219,7 @@ function Kobo:resume()
-- kernel to suspend/resume various subsystems
-- cf. kernel/power/main.c @ L#207
-- Among other things, this sets up the wakeup pins (e.g., resume on input).
local ret = writeToSys("0", "/sys/power/state-extended")
local ret = util.writeToSysfs("0", "/sys/power/state-extended")
if ret then
logger.dbg("Kobo resume: successfully asked the kernel to resume subsystems")
else
@ -1254,7 +1235,7 @@ function Kobo:resume()
-- c.f., neo_ctl @ drivers/input/touchscreen/zforce_i2c.c,
-- basically, a is wakeup (for activate), d is sleep (for deactivate), and we don't care about s (set res),
-- and l (led signal level, actually a NOP on NTX kernels).
writeToSys("a", self.hasIRGridSysfsKnob)
util.writeToSysfs("a", self.hasIRGridSysfsKnob)
end
-- A full suspend may have toggled the LED off.
@ -1367,16 +1348,16 @@ function Kobo:enableCPUCores(amount)
up = "1"
end
writeToSys(up, path)
util.writeToSysfs(up, path)
end
end
function Kobo:performanceCPUGovernor()
writeToSys("performance", self.cpu_governor_knob)
util.writeToSysfs("performance", self.cpu_governor_knob)
end
function Kobo:defaultCPUGovernor()
writeToSys(self.default_cpu_governor, self.cpu_governor_knob)
util.writeToSysfs(self.default_cpu_governor, self.cpu_governor_knob)
end
function Kobo:isStartupScriptUpToDate()

@ -2,12 +2,8 @@
-- This also supports the natural light, which consists of additional
-- red and green light LEDs.
local logger = require("logger")
local dbg = require("dbg")
local ffi = require("ffi")
local C = ffi.C
require("ffi/posix_h")
local util = require("util")
local SysfsLight = {
frontlight_white = nil,
@ -77,15 +73,15 @@ function SysfsLight:setNaturalBrightness(brightness, warmth)
if self.frontlight_ioctl then
self.frontlight_ioctl:setBrightness(brightness)
else
self:_write_value(self.frontlight_white, brightness)
util.writeToSysfs(brightness, self.frontlight_white)
end
end
-- The mixer might be using inverted values... (cold is nl_max, warm is nl_min)
if set_warmth then
if self.nl_inverted then
self:_write_value(self.frontlight_mixer, self.nl_max - warmth)
util.writeToSysfs(self.nl_max - warmth, self.frontlight_mixer)
else
self:_write_value(self.frontlight_mixer, warmth)
util.writeToSysfs(warmth, self.frontlight_mixer)
end
end
else
@ -128,30 +124,11 @@ function SysfsLight:_set_light_value(sysfs_directory, value)
if not sysfs_directory then return end
-- bl_power is '31' when the light is turned on, '0' otherwise.
if (value > 0) then
self:_write_value(sysfs_directory .. "/bl_power", 31)
util.writeToSysfs(31, sysfs_directory .. "/bl_power")
else
self:_write_value(sysfs_directory .. "/bl_power", 0)
end
self:_write_value(sysfs_directory .. "/brightness", value)
end
function SysfsLight:_write_value(file, val)
local fd = C.open(file, bit.bor(C.O_WRONLY, C.O_CLOEXEC)) -- procfs/sysfs, we shouldn't need O_TRUNC
if fd == -1 then
logger.err("Cannot open file `" .. file .. "`:", ffi.string(C.strerror(ffi.errno())))
return false
end
val = tostring(val)
local bytes = #val
local nw = C.write(fd, val, bytes)
if nw == -1 then
logger.err("Cannot write `" .. val .. "` to file `" .. file .. "`:", ffi.string(C.strerror(ffi.errno())))
C.close(fd)
return false
util.writeToSysfs(0, sysfs_directory .. "/bl_power")
end
C.close(fd)
-- NOTE: Allows the caller to possibly handle short writes (not that these should ever happen here).
return nw == bytes
util.writeToSysfs(value, sysfs_directory .. "/brightness")
end
return SysfsLight

@ -4,6 +4,7 @@ local Event = require("ui/event")
local InfoMessage = require("ui/widget/infomessage")
local Language = require("ui/language")
local NetworkMgr = require("ui/network/manager")
local PowerD = Device:getPowerDevice()
local UIManager = require("ui/uimanager")
local _ = require("gettext")
local N_ = _.ngettext
@ -236,6 +237,17 @@ if Device:isKobo() then
}
end
if Device:isKindle() and PowerD:hasHallSensor() then
common_settings.cover_events = {
text = _("Disable Kindle cover events"),
help_text = _([[Toggle the Hall effect sensor.
This is used to detect if the cover is closed, which will automatically sleep and wake the device. If there is no cover present the sensor may cause spurious wakeups when located next to a magnetic source.]]),
keep_menu_open = true,
checked_func = function() return not PowerD:isHallSensorEnabled() end,
callback = function() PowerD:onToggleHallSensor() end,
}
end
common_settings.night_mode = {
text = _("Night mode"),
checked_func = function() return G_reader_settings:isTrue("night_mode") end,

@ -58,6 +58,7 @@ local order = {
"autoshutdown",
"ignore_sleepcover",
"ignore_open_sleepcover",
"cover_events",
"ignore_battery_optimizations",
"mass_storage_settings", -- if Device:canToggleMassStorage()
"file_ext_assoc",

@ -102,6 +102,7 @@ local order = {
"autoshutdown",
"ignore_sleepcover",
"ignore_open_sleepcover",
"cover_events",
"ignore_battery_optimizations",
"mass_storage_settings", -- if Device:canToggleMassStorage()
"file_ext_assoc",

@ -5,9 +5,13 @@ This module contains miscellaneous helper functions for the KOReader frontend.
local BaseUtil = require("ffi/util")
local Utf8Proc = require("ffi/utf8proc")
local lfs = require("libs/libkoreader-lfs")
local logger = require("logger")
local _ = require("gettext")
local C_ = _.pgettext
local T = BaseUtil.template
local ffi = require("ffi")
local C = ffi.C
require("ffi/posix_h")
local lshift = bit.lshift
local rshift = bit.rshift
@ -829,6 +833,26 @@ function util.removeFile(file)
end
end
function util.writeToSysfs(val, file)
-- NOTE: We do things by hand via ffi, because io.write uses fwrite,
-- which isn't a great fit for procfs/sysfs (e.g., we lose failure cases like EBUSY,
-- as it only reports failures to write to the *stream*, not to the disk/file!).
local fd = C.open(file, bit.bor(C.O_WRONLY, C.O_CLOEXEC)) -- procfs/sysfs, we shouldn't need O_TRUNC
if fd == -1 then
logger.err("Cannot open file `" .. file .. "`:", ffi.string(C.strerror(ffi.errno())))
return
end
val = tostring(val)
local bytes = #val
local nw = C.write(fd, val, bytes)
if nw == -1 then
logger.err("Cannot write `" .. val .. "` to file `" .. file .. "`:", ffi.string(C.strerror(ffi.errno())))
end
C.close(fd)
-- NOTE: Allows the caller to possibly handle short writes (not that these should ever happen here).
return nw == bytes
end
-- Gets total, used and available bytes for the mountpoint that holds a given directory.
-- @string path of the directory
-- @treturn table with total, used and available bytes

@ -40,7 +40,6 @@ describe("device module", function()
after_each(function()
mock_input.open:revert()
os.getenv:revert()
os.execute:revert()
os.getenv = osgetenv
io.open = iopen
@ -278,8 +277,6 @@ describe("device module", function()
assert.is.same(kindle_dev.powerd.fl_intensity, 5)
kindle_dev.powerd:toggleFrontlight()
assert.stub(os.execute).was_called_with(
"printf '%s' 0 > /sys/class/backlight/max77696-bl/brightness")
-- Here be shenanigans: we don't override powerd's fl_intensity when we turn the light off,
-- so that we can properly turn it back on at the previous intensity ;)
assert.is.same(kindle_dev.powerd.fl_intensity, 5)

Loading…
Cancel
Save