162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * netup-init.c 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * NetUP Dual DVB-S2 CI driver 662306a36Sopenharmony_ci * 762306a36Sopenharmony_ci * Copyright (C) 2009 NetUP Inc. 862306a36Sopenharmony_ci * Copyright (C) 2009 Igor M. Liplianin <liplianin@netup.ru> 962306a36Sopenharmony_ci * Copyright (C) 2009 Abylay Ospan <aospan@netup.ru> 1062306a36Sopenharmony_ci */ 1162306a36Sopenharmony_ci 1262306a36Sopenharmony_ci#include "cx23885.h" 1362306a36Sopenharmony_ci#include "netup-init.h" 1462306a36Sopenharmony_ci 1562306a36Sopenharmony_cistatic void i2c_av_write(struct i2c_adapter *i2c, u16 reg, u8 val) 1662306a36Sopenharmony_ci{ 1762306a36Sopenharmony_ci int ret; 1862306a36Sopenharmony_ci u8 buf[3]; 1962306a36Sopenharmony_ci struct i2c_msg msg = { 2062306a36Sopenharmony_ci .addr = 0x88 >> 1, 2162306a36Sopenharmony_ci .flags = 0, 2262306a36Sopenharmony_ci .buf = buf, 2362306a36Sopenharmony_ci .len = 3 2462306a36Sopenharmony_ci }; 2562306a36Sopenharmony_ci 2662306a36Sopenharmony_ci buf[0] = reg >> 8; 2762306a36Sopenharmony_ci buf[1] = reg & 0xff; 2862306a36Sopenharmony_ci buf[2] = val; 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ci ret = i2c_transfer(i2c, &msg, 1); 3162306a36Sopenharmony_ci 3262306a36Sopenharmony_ci if (ret != 1) 3362306a36Sopenharmony_ci pr_err("%s: i2c write error!\n", __func__); 3462306a36Sopenharmony_ci} 3562306a36Sopenharmony_ci 3662306a36Sopenharmony_cistatic void i2c_av_write4(struct i2c_adapter *i2c, u16 reg, u32 val) 3762306a36Sopenharmony_ci{ 3862306a36Sopenharmony_ci int ret; 3962306a36Sopenharmony_ci u8 buf[6]; 4062306a36Sopenharmony_ci struct i2c_msg msg = { 4162306a36Sopenharmony_ci .addr = 0x88 >> 1, 4262306a36Sopenharmony_ci .flags = 0, 4362306a36Sopenharmony_ci .buf = buf, 4462306a36Sopenharmony_ci .len = 6 4562306a36Sopenharmony_ci }; 4662306a36Sopenharmony_ci 4762306a36Sopenharmony_ci buf[0] = reg >> 8; 4862306a36Sopenharmony_ci buf[1] = reg & 0xff; 4962306a36Sopenharmony_ci buf[2] = val & 0xff; 5062306a36Sopenharmony_ci buf[3] = (val >> 8) & 0xff; 5162306a36Sopenharmony_ci buf[4] = (val >> 16) & 0xff; 5262306a36Sopenharmony_ci buf[5] = val >> 24; 5362306a36Sopenharmony_ci 5462306a36Sopenharmony_ci ret = i2c_transfer(i2c, &msg, 1); 5562306a36Sopenharmony_ci 5662306a36Sopenharmony_ci if (ret != 1) 5762306a36Sopenharmony_ci pr_err("%s: i2c write error!\n", __func__); 5862306a36Sopenharmony_ci} 5962306a36Sopenharmony_ci 6062306a36Sopenharmony_cistatic u8 i2c_av_read(struct i2c_adapter *i2c, u16 reg) 6162306a36Sopenharmony_ci{ 6262306a36Sopenharmony_ci int ret; 6362306a36Sopenharmony_ci u8 buf[2]; 6462306a36Sopenharmony_ci struct i2c_msg msg = { 6562306a36Sopenharmony_ci .addr = 0x88 >> 1, 6662306a36Sopenharmony_ci .flags = 0, 6762306a36Sopenharmony_ci .buf = buf, 6862306a36Sopenharmony_ci .len = 2 6962306a36Sopenharmony_ci }; 7062306a36Sopenharmony_ci 7162306a36Sopenharmony_ci buf[0] = reg >> 8; 7262306a36Sopenharmony_ci buf[1] = reg & 0xff; 7362306a36Sopenharmony_ci 7462306a36Sopenharmony_ci ret = i2c_transfer(i2c, &msg, 1); 7562306a36Sopenharmony_ci 7662306a36Sopenharmony_ci if (ret != 1) 7762306a36Sopenharmony_ci pr_err("%s: i2c write error!\n", __func__); 7862306a36Sopenharmony_ci 7962306a36Sopenharmony_ci msg.flags = I2C_M_RD; 8062306a36Sopenharmony_ci msg.len = 1; 8162306a36Sopenharmony_ci 8262306a36Sopenharmony_ci ret = i2c_transfer(i2c, &msg, 1); 8362306a36Sopenharmony_ci 8462306a36Sopenharmony_ci if (ret != 1) 8562306a36Sopenharmony_ci pr_err("%s: i2c read error!\n", __func__); 8662306a36Sopenharmony_ci 8762306a36Sopenharmony_ci return buf[0]; 8862306a36Sopenharmony_ci} 8962306a36Sopenharmony_ci 9062306a36Sopenharmony_cistatic void i2c_av_and_or(struct i2c_adapter *i2c, u16 reg, unsigned and_mask, 9162306a36Sopenharmony_ci u8 or_value) 9262306a36Sopenharmony_ci{ 9362306a36Sopenharmony_ci i2c_av_write(i2c, reg, (i2c_av_read(i2c, reg) & and_mask) | or_value); 9462306a36Sopenharmony_ci} 9562306a36Sopenharmony_ci/* set 27MHz on AUX_CLK */ 9662306a36Sopenharmony_civoid netup_initialize(struct cx23885_dev *dev) 9762306a36Sopenharmony_ci{ 9862306a36Sopenharmony_ci struct cx23885_i2c *i2c_bus = &dev->i2c_bus[2]; 9962306a36Sopenharmony_ci struct i2c_adapter *i2c = &i2c_bus->i2c_adap; 10062306a36Sopenharmony_ci 10162306a36Sopenharmony_ci /* Stop microcontroller */ 10262306a36Sopenharmony_ci i2c_av_and_or(i2c, 0x803, ~0x10, 0x00); 10362306a36Sopenharmony_ci 10462306a36Sopenharmony_ci /* Aux PLL frac for 27 MHz */ 10562306a36Sopenharmony_ci i2c_av_write4(i2c, 0x114, 0xea0eb3); 10662306a36Sopenharmony_ci 10762306a36Sopenharmony_ci /* Aux PLL int for 27 MHz */ 10862306a36Sopenharmony_ci i2c_av_write4(i2c, 0x110, 0x090319); 10962306a36Sopenharmony_ci 11062306a36Sopenharmony_ci /* start microcontroller */ 11162306a36Sopenharmony_ci i2c_av_and_or(i2c, 0x803, ~0x10, 0x10); 11262306a36Sopenharmony_ci} 113