#!/usr/bin/env python3 ### # Dependencies: Linux, python3, python3-smbus # Usage: `sudo ./set_lp8550_slope.py` # # Default slope is 0b101=200ms, can be adjusted below # Tested with Ubuntu 20.04 on A1466 2013 # All original EEPROM registers value: # - A0: 0b01111111 # - A1: 0b10110101 # - A2: 0b10111111 # - A3: 0b01111011 # - A4: 0b00101000 # - A5: 0b11001111 # - A6: 0b01100100 # - A7: 0b00101101 ### import time import smbus2 config = { 'smbus_address': 0, # SMBus address, can use `i2cdetect -l` to find it 'device_address': 0x2C, # LP8550 7 bits address 'slope': (1, 0, 1) # The new slope to set, MSB first, see lp8550 datasheet 8.6.2.3 SLOPE } lp8550_regs = { 'EEPROMControl': 0x72, 'EEPROMAddress1': 0xA1 # default value for this register is 0b10110101 on original 820-3437 } def bitstolist(val, regsize=8): return [(val >> i) & 0b1 for i in range(0, regsize)] def listtobits(l, regsize=8): val = 0 for i in range(0, regsize): val += l[i] << i return val def read_reg(bus, dev_address, reg_name): return bitstolist(bus.read_byte_data(dev_address, lp8550_regs[reg_name])) def write_reg(bus, dev_address, reg_name, reg): print(f'Writing { listtobits(reg)} to {dev_address}, {lp8550_regs[reg_name]}') bus.write_byte_data(dev_address, lp8550_regs[reg_name], listtobits(reg)) def get_slope(bus, dev_address): return read_reg(bus, dev_address, 'EEPROMAddress1')[0:3][::-1] def set_slope(bus, dev_address, slope): print('Original slope: ', get_slope(bus, dev_address)) EEPROMAddress1 = read_reg(bus, dev_address, 'EEPROMAddress1') EEPROMAddress1[0:3] = slope[::-1] write_reg(bus, dev_address, 'EEPROMAddress1', EEPROMAddress1) print('New slope: ', get_slope(bus, dev_address)) def write_nvm(bus, dev_address): print('Writing to non-volatile memory') EEPROMControl = [0]*8 EEPROMControl[2] = 1 # EE_INIT=1 write_reg(bus, dev_address, 'EEPROMControl', EEPROMControl) EEPROMControl[1] = 1 # EE_PROG=1 EEPROMControl[2] = 0 # EE_INIT=0 write_reg(bus, dev_address, 'EEPROMControl', EEPROMControl) time.sleep(0.2) # wait 200ms EEPROMControl[1] = 0 # EE_PROG=0 write_reg(bus, dev_address, 'EEPROMControl', EEPROMControl) def load_nvm(bus, dev_address): print('Loading from non-volatile memory') EEPROMControl = [0]*8 EEPROMControl[2] = 1 # EE_INIT=1 write_reg(bus, dev_address, 'EEPROMControl', EEPROMControl) EEPROMControl[0] = 1 # EE_READ=1 EEPROMControl[2] = 0 # EE_INIT=0 write_reg(bus, dev_address, 'EEPROMControl', EEPROMControl) time.sleep(0.2) # wait 200ms EEPROMControl[0] = 0 # EE_READ=0 write_reg(bus, dev_address, 'EEPROMControl', EEPROMControl) def main(): bus = smbus2.SMBus(config['smbus_address']) set_slope(bus, config['device_address'], config['slope']) write_nvm(bus, config['device_address']) load_nvm(bus, config['device_address']) print('Slope in non-volatile memory: ', get_slope(bus,config['device_address'])) if __name__ == "__main__": main()