Hi,
We want to add a low-battery warning on Photonicat 2 running Debian.
The idea is simple: when the battery drops to a low level, the device should beep a few times, and if power is not connected, our script will shut it down safely.
The device already makes a beep when the physical power button is pressed, so there is clearly some sound emitter on the board. But we cannot find how to trigger it from Linux.
What we checked:
- ALSA is present, but only HDMI audio is exposed.
-
/sys/bus/platform/drivers/pwm-beeper exists, but no device is bound to it.
- No
pwm-beeper, gpio-beeper, buzzer, or speaker node appears in the device tree.
-
/proc/bus/input/devices shows rk805 pwrkey, but no beeper/speaker input device.
- The PMIC is exposed as RK806/RK805-related devices, but we only see
gpio_pwrctrl1/2/3, which look like power-control/DVS pins, not something safe to use as a buzzer without documentation.
Question:
Is the built-in beep controllable from Debian/Linux?
If yes, what is the correct interface?
- GPIO?
- PWM?
- I2C / PMIC register?
- EC/vendor command?
- device-tree overlay?
We do not want to poke random GPIO/PWM/PMIC registers blindly. We just need a safe supported way to trigger the same beep that happens when the power button is pressed.
Thanks.
Hello,
The beeper is controlled by MCU, not SoC itself. You need to send commands to MCU (to device /dev/pcat-pm-ctl).
Here is a sample code for it:
#!/usr/bin/env python3
import os
def pcat_pmu_compute_crc16(data):
crc = 0xFFFF;
i = 0
for x in data:
crc ^= data[i]
for j in range(0, 8):
if crc & 1:
crc = (crc >> 1) ^ 0xA001
else:
crc >>= 1
crc &= 0xFFFF
i += 1
return crc
def pcat_pmu_pm_dev_write_data_request(fd, command, extra_data, need_ack):
payload = bytearray()
payload += b"\xA5\x01\x81\x00\x00"
if extra_data is not None and len(extra_data) > 0 and len(extra_data) <= 65532:
extra_data_len = len(extra_data) + 3
payload.append(extra_data_len & 0xFF)
payload.append((extra_data_len >> 8) & 0xFF)
payload.append(command & 0xFF)
payload.append((command >> 8) & 0xFF)
payload += extra_data
else:
payload += '\x03\x00'
payload.append(command & 0xFF)
payload.append((command >> 8) & 0xFF)
if(need_ack):
payload.append(1)
else:
payload.append(0)
crc = pcat_pmu_compute_crc16(payload[1:])
payload.append(crc & 0xFF)
payload.append((crc >> 8) & 0xFF)
payload.append(0x5A)
fd.write(payload)
#Beep event 1
freq1 = 1000 # in Hz, set to 0 for silent
duration1 = 500 # in ms, must larger than 0
loop = False # Set to True for looping,
extra_data = bytearray()
extra_data.append(freq1 & 0xFF)
extra_data.append((freq1 >> 8) & 0xFF)
extra_data.append(duration1 & 0xFF)
extra_data.append((duration1 >> 8) & 0xFF)
#Beep event 2 or more, optional, maximum number of beep event is 20
#freq2 = 500
#duration2 = 500
#extra_data.append(freq2 & 0xFF)
#extra_data.append((freq2 >> 8) & 0xFF)
#extra_data.append(duration2 & 0xFF)
#extra_data.append((duration2 >> 8) & 0xFF)
if loop:
extra_data.append(0)
else:
extra_data.append(1)
fd = open('/dev/pcat-pm-ctl', 'wb')
pcat_pmu_pm_dev_write_data_request(fd, 163, extra_data, False)
fd.close()