/*
 * Read a value from a register on ADV7525 device
 * If sucessfull returns value read , otherwise error.
 */
static u8 adv7525_read_reg(struct i2c_client *client, u8 reg)
{
	int err;
	struct i2c_msg msg[2];
	u8 reg_buf[] = { reg };
	u8 data_buf[] = { 0 };

	if (!client->adapter)
		return -ENODEV;
	if (!gpio_power_on) {
		DEV_WARN("%s: WARN: missing GPIO power\n", __func__);
		return -ENODEV;
	}
	msg[0].addr = client->addr;
	msg[0].flags = 0;
	msg[0].len = 1;
	msg[0].buf = reg_buf;

	msg[1].addr = client->addr;
	msg[1].flags = I2C_M_RD;
	msg[1].len = 1;
	msg[1].buf = data_buf;

	err = i2c_transfer(client->adapter, msg, 2);
	if (err < 0) {
		DEV_INFO("%s: I2C err: %d\n", __func__, err);
		return err;
	}

#ifdef PORT_DEBUG
	DEV_INFO("HDMI[%02x] [R] %02x\n", reg, data);
#endif
	return *data_buf;
}
static ssize_t hdmi_common_wta_video_mode(struct device *dev,
        struct device_attribute *attr, const char *buf, size_t count)
{
    ssize_t ret = strnlen(buf, PAGE_SIZE);
    uint32 video_mode;
    const struct hdmi_disp_mode_timing_type *disp_mode;

    mutex_lock(&hdmi_common_state_hpd_mutex);
    if (!hdmi_common_state->hpd_state) {
        mutex_unlock(&hdmi_common_state_hpd_mutex);
        DEV_INFO("%s: FAILED: display off or cable disconnected\n",
                 __func__);
        return ret;
    }
    mutex_unlock(&hdmi_common_state_hpd_mutex);

    video_mode = atoi(buf)-1;
    disp_mode = hdmi_common_get_supported_mode(video_mode);
    if (!disp_mode) {
        DEV_INFO("%s: FAILED: mode not supported (%d)\n",
                 __func__, video_mode);
        return ret;
    }

    kobject_uevent(hdmi_common_state->uevent_kobj, KOBJ_OFFLINE);

    hdmi_common_state->disp_mode_list.num_of_elements = 1;
    hdmi_common_state->disp_mode_list.disp_mode_list[0] = video_mode;
    DEV_DBG("%s: 'mode=%d %s' successful (sending OFF/ONLINE)\n", __func__,
            video_mode, video_format_2string(video_mode));

    kobject_uevent(hdmi_common_state->uevent_kobj, KOBJ_ONLINE);
    return ret;
}
Ejemplo n.º 3
0
bool CGameServer::OnServerUpdate(CPAKUpdate* pUpdate, KeyRef krSocket)
{
	bool bRet = false;
	switch (pUpdate->GetType()) {
	case PAK_TYPE_ZONE:
		{
			DEV_INFO(TF("[游戏服务器]地图服务器[%p]更新"), krSocket);
			bRet = ServerUpdate<SVR_ZONE_INDEX_MAP, DATA_INDEX_ZONE, INFOI_ZONE>(pUpdate, (DataRef)krSocket, m_ZoneSvrMap);
		}
		break;
	case PAK_TYPE_GATE:
		{
			DEV_INFO(TF("[游戏服务器]网关服务器[%p]更新"), krSocket);
			bRet = ServerUpdate<SVR_GATE_MAP, DATA_INDEX_GATE, INFOI_GATE>(pUpdate, (DataRef)krSocket, m_GateSvrMap);
		}
		break;
	default:
		{
			LOGV_WARN(m_FileLog, TF("[游戏服务器]%p无法识别的%X服务器信令包数据"), krSocket, pUpdate->GetType());
		}
	}
	if (bRet) {
		// 发送更新回执包
		CPAKSimple<PAK_EVENT_UPDATEACK, PAK_TYPE_GAME> UpdateAck;
		UpdateAck.AdjustSize();
		m_NetworkPtr->Send(krSocket, UpdateAck);
	}
	return bRet;
}
Ejemplo n.º 4
0
bool CGameServer::OnShareUpdate(CEventBase& EventRef, LLong llParam)
{
	CPAKUpdate* pUpdate = static_cast<CPAKUpdate*>(&EventRef);
	if (pUpdate->GetType() == PAK_TYPE_ZONE) {
		if (m_pShareZoneSvr != nullptr) {
			DEV_INFO(TF("[游戏服务器]同进程地图服务器[%p]更新"), m_pShareZoneSvr);
			assert(m_pShareZoneSvr == reinterpret_cast<ICommonServer*>(llParam));
			return ServerUpdate<SVR_ZONE_INDEX_MAP, DATA_INDEX_ZONE, INFOI_ZONE>(pUpdate, (DataRef)llParam, m_ZoneSvrMap);
		}
		else {
			LOGV_WARN(m_FileLog, TF("[游戏服务器]同进程地图服务器对象未注册"));
		}
	}
	else if (pUpdate->GetType() == PAK_TYPE_GATE) {
		if (m_pShareGateSvr != nullptr) {
			DEV_INFO(TF("[游戏服务器]同进程网关服务器[%p]更新"), m_pShareGateSvr);
			assert(m_pShareGateSvr == reinterpret_cast<ICommonServer*>(llParam));
			return ServerUpdate<SVR_GATE_MAP, DATA_INDEX_GATE, INFOI_GATE>(pUpdate, (DataRef)llParam, m_GateSvrMap);
		}
		else {
			LOGV_WARN(m_FileLog, TF("[游戏服务器]同进程网关服务器对象未注册"));
		}
	}
	return false;
}
Ejemplo n.º 5
0
static void adv7520_hdcp_enable(struct work_struct *work)
{
	DEV_INFO("HDCP: Start reg[0xaf]=%02x (mute audio)\n", reg[0xaf]);

	adv7520_comm_power(1, 1);

	/* Mute Audio */
	adv7520_write_reg(hclient, 0x0C, (u8)0xC3);

	msleep(200);
	/* Wait for BKSV ready interrupt */
	/* Read BKSV's keys from HDTV */
	reg[0xBF] = adv7520_read_reg(hclient, 0xBF);
	reg[0xC0] = adv7520_read_reg(hclient, 0xC0);
	reg[0xC1] = adv7520_read_reg(hclient, 0xC1);
	reg[0xC2] = adv7520_read_reg(hclient, 0xC2);
	reg[0xc3] = adv7520_read_reg(hclient, 0xC3);

	DEV_DBG("HDCP: BKSV={%02x,%02x,%02x,%02x,%02x}\n", reg[0xbf], reg[0xc0],
		reg[0xc1], reg[0xc2], reg[0xc3]);

	/* Is SINK repeater */
	reg[0xBE] = adv7520_read_reg(hclient, 0xBE);
	if (~(reg[0xBE] & 0x40)) {
		; /* compare with revocation list */
		/* Check 20 1's and 20 zero's */
	} else {
		/* Don't implement HDCP if sink as a repeater */
		adv7520_write_reg(hclient, 0x0C, (u8)0x84);
		mutex_lock(&hdcp_state_mutex);
		hdcp_activating = FALSE;
		mutex_unlock(&hdcp_state_mutex);
		DEV_WARN("HDCP: Sink Repeater (%02x), (unmute audio)\n",
			reg[0xbe]);

		adv7520_comm_power(0, 1);
		return;
	}

	msleep(200);
	reg[0xB8] = adv7520_read_reg(hclient, 0xB8);
	DEV_INFO("HDCP: Status reg[0xB8] is %02x\n", reg[0xb8]);
	if (reg[0xb8] & 0x40) {
		/* UnMute Audio */
		adv7520_write_reg(hclient, 0x0C, (u8)0x84);
		DEV_INFO("HDCP: A/V content Encrypted (unmute audio)\n");
		external_common_state->hdcp_active = TRUE;
	}
	adv7520_comm_power(0, 1);

	mutex_lock(&hdcp_state_mutex);
	hdcp_activating = FALSE;
	mutex_unlock(&hdcp_state_mutex);
}
Ejemplo n.º 6
0
static void adv7520_hdcp_enable(struct work_struct *work)
{
	DEV_INFO("HDCP: Start reg[0xaf]=%02x (mute audio)\n", reg[0xaf]);

	adv7520_comm_power(1, 1);

	
	adv7520_write_reg(hclient, 0x0C, (u8)0xC3);

	msleep(200);
	
	
	reg[0xBF] = adv7520_read_reg(hclient, 0xBF);
	reg[0xC0] = adv7520_read_reg(hclient, 0xC0);
	reg[0xC1] = adv7520_read_reg(hclient, 0xC1);
	reg[0xC2] = adv7520_read_reg(hclient, 0xC2);
	reg[0xc3] = adv7520_read_reg(hclient, 0xC3);

	DEV_DBG("HDCP: BKSV={%02x,%02x,%02x,%02x,%02x}\n", reg[0xbf], reg[0xc0],
		reg[0xc1], reg[0xc2], reg[0xc3]);

	
	reg[0xBE] = adv7520_read_reg(hclient, 0xBE);
	if (~(reg[0xBE] & 0x40)) {
		; 
		
	} else {
		
		adv7520_write_reg(hclient, 0x0C, (u8)0x84);
		mutex_lock(&hdcp_state_mutex);
		hdcp_activating = FALSE;
		mutex_unlock(&hdcp_state_mutex);
		DEV_WARN("HDCP: Sink Repeater (%02x), (unmute audio)\n",
			reg[0xbe]);

		adv7520_comm_power(0, 1);
		return;
	}

	msleep(200);
	reg[0xB8] = adv7520_read_reg(hclient, 0xB8);
	DEV_INFO("HDCP: Status reg[0xB8] is %02x\n", reg[0xb8]);
	if (reg[0xb8] & 0x40) {
		
		adv7520_write_reg(hclient, 0x0C, (u8)0x84);
		DEV_INFO("HDCP: A/V content Encrypted (unmute audio)\n");
		external_common_state->hdcp_active = TRUE;
	}
	adv7520_comm_power(0, 1);

	mutex_lock(&hdcp_state_mutex);
	hdcp_activating = FALSE;
	mutex_unlock(&hdcp_state_mutex);
}
static void adv7525_hdcp_link_work(struct work_struct *work)
{
	u8 reg0xb8 = adv7525_read_reg(hclient_main, 0xb8);

	if (reg0xb8 & (1 << 6)) {
		DEV_INFO("%s: HDCP Link OK\n", __func__);
		mod_timer(&hdcp_link_timer, jiffies + msecs_to_jiffies(2000));
	} else {
		/* clear HDCP request */
		adv7525_write_reg_mask(hclient_main, 0xaf, 0x1, 7, 0);
		adv7525_write_reg_mask(hclient_main, 0xaf, 0x1, 7, 1);
		DEV_INFO("%s: clear HDCP reg[0xaf]=0x%02x\n",
					__func__, reg[0xaf]);
	}
}
Ejemplo n.º 8
0
/*
 * Write a value to a register on adv7520 device.
 * Returns zero if successful, or non-zero otherwise.
 */
static int adv7520_write_reg(struct i2c_client *client, u8 reg, u8 val)
{
	int err;
	struct i2c_msg msg[1];
	unsigned char data[2];

	if (!client->adapter)
		return -ENODEV;
	if (!atomic_read(&comm_power_on)) {
		DEV_WARN("%s: WARN: missing GPIO power\n", __func__);
		return -ENODEV;
	}

	msg->addr = client->addr;
	msg->flags = 0;
	msg->len = 2;
	msg->buf = data;
	data[0] = reg;
	data[1] = val;

	err = i2c_transfer(client->adapter, msg, 1);
	if (err >= 0)
		return 0;
#ifdef PORT_DEBUG
	DEV_INFO("HDMI[%02x] [W] %02x [%d]\n", reg, val, err);
#endif
	return err;
}
Ejemplo n.º 9
0
bool CGameServer::DispatchGameDBServer(const PacketPtr& PktPtr, KeyRef krSocket)
{
	switch (PktPtr->GetEvent()) {
	case PAK_EVENT_LINKACK:
		{
			m_bGameDBLinked = true;

			NET_ADDR NetAddr;
			m_NetworkPtr->GetAddr(krSocket, NetAddr, false);
			m_pUIHandler->OnHandle(PAK_EVENT_LINK, reinterpret_cast<uintptr_t>(&NetAddr), DATA_INDEX_GAMEDB);
			LOG_INFO(m_FileLog, TF("[游戏服务器]收到游戏DB服务器注册回复包"));
		}
		break;
	case PAK_EVENT_UPDATEACK:
		{
			DEV_INFO(TF("[游戏服务器]收到游戏DB服务器更新回复包"));
		}
		break;
	case PAK_EVENT_UNLINKACK:
		{
			m_bGameDBLinked = false;
			LOG_INFO(m_FileLog, TF("[游戏服务器]收到游戏DB服务器注销回复包"));
		}
		break;
	case PAK_EVENT_LIVEACK:
		{
		}
		break;
	default:
		{
			LOGV_WARN(m_FileLog, TF("[游戏服务器]%p无法识别的游戏DB服务器信令包数据[event=%d]"), krSocket, PktPtr->GetEvent());
		}
	}
	return true;
}
Ejemplo n.º 10
0
//--------------------------------------
bool CGameServer::OnUdpClose(KeyRef krSocket, LLong)
{
	if (krSocket == m_krUDPService){
		m_krUDPService = nullptr;
		DEV_INFO(TF("[游戏服务器]UDP监听登陆服务器关闭"));
	}
	return true;
}
int adv7525_i2c_write(struct i2c_client *client, char *buf, int count)
{
	if (count != i2c_master_send(client, buf, count)) {
		DEV_INFO("%s: i2c write err\n", __func__);
		return -EBUSY;
	}
	return 0;
}
Ejemplo n.º 12
0
static ssize_t external_common_wta_video_mode(struct device *dev,
	struct device_attribute *attr, const char *buf, size_t count)
{
	ssize_t ret = strnlen(buf, PAGE_SIZE);
	uint32 video_mode;
#ifdef CONFIG_FB_MSM_HDMI_COMMON
	const struct hdmi_disp_mode_timing_type *disp_mode;
#endif
	mutex_lock(&external_common_state_hpd_mutex);
	if (!external_common_state->hpd_state) {
		mutex_unlock(&external_common_state_hpd_mutex);
		DEV_INFO("%s: FAILED: display off or cable disconnected\n",
			__func__);
		return ret;
	}
	mutex_unlock(&external_common_state_hpd_mutex);

	video_mode = atoi(buf)-1;
	kobject_uevent(external_common_state->uevent_kobj, KOBJ_OFFLINE);
#ifdef CONFIG_FB_MSM_HDMI_COMMON
	disp_mode = hdmi_common_get_supported_mode(video_mode);
	if (!disp_mode) {
		DEV_INFO("%s: FAILED: mode not supported (%d)\n",
			__func__, video_mode);
		return ret;
	}
	external_common_state->disp_mode_list.num_of_elements = 1;
	external_common_state->disp_mode_list.disp_mode_list[0] = video_mode;
#elif defined(CONFIG_FB_MSM_TVOUT)
	external_common_state->tvout_enable(0);
	external_common_state->video_resolution = video_mode;
	external_common_state->tvout_enable(1);
#endif
	DEV_DBG("%s: 'mode=%d %s' successful (sending OFF/ONLINE)\n", __func__,
		video_mode, video_format_2string(video_mode));
	kobject_uevent(external_common_state->uevent_kobj, KOBJ_ONLINE);
	return ret;
}
Ejemplo n.º 13
0
//--------------------------------------
bool CGameServer::OnTcpConnect(UInt uError, KeyRef krConnect)
{
	if (krConnect == m_krConnectCenter) {
		m_bCenterCnnted = (uError == 0);
		if (m_bCenterCnnted) {
			LinkCenterServer();
		}
		else {
			DEV_INFO(TF("[游戏服务器]连接中心服务器失败%X!"), uError);
			LOGV_WARN(m_FileLog, TF("[游戏服务器]连接中心服务器失败%X!"), uError);
		}
	}
	else if (krConnect == m_krConnectGameDB) {
		m_bGameDBCnnted = (uError == 0);
		if (m_bGameDBCnnted) {
			LinkGameDBServer();
		}
		else {
			DEV_INFO(TF("[游戏服务器]连接游戏DB服务器失败%X!"), uError);
			LOGV_WARN(m_FileLog, TF("[游戏服务器]连接游戏DB服务器失败%X!"), uError);
		}
	}
	return true;
}
Ejemplo n.º 14
0
//--------------------------------------
bool CGameServer::OnTcpAccept(KeyRef krAccept, KeyRef)
{
	if (m_nStatus == STATUSC_RUN) {
		UShort     usPort = 0;
		CStringKey strAddr;
		m_NetworkPtr->GetAddr(krAccept, strAddr, usPort);

		DEV_INFO(TF("[游戏服务器]服务器[%s]:%d连接完成!"), *strAddr, usPort);
		m_ServerInfo.Incr();
		return true;
	}
	else {
		LOGV_WARN(m_FileLog, TF("[游戏服务器]游戏服务器处于暂停状态!"));
	}
	return false;
}
Ejemplo n.º 15
0
//--------------------------------------
bool CGameServer::OnTcpClose(KeyRef krSocket, LLong llLiveData)
{
	if (krSocket == m_krConnectCenter) {
		m_krConnectCenter = nullptr;
		m_bCenterCnnted   = false;
		m_bCenterLinked   = false;
		m_pUIHandler->OnHandle(PAK_EVENT_UNLINK, 0, DATA_INDEX_CENTER);
		DEV_INFO(TF("[游戏服务器]连接中心服务器断开"));
		LOG_INFO(m_FileLog, TF("[游戏服务器]连接中心服务器断开"));
	}
	else if (krSocket == m_krConnectGameDB) {
		m_krConnectGameDB = nullptr;
		m_bGameDBCnnted   = false;
		m_bGameDBLinked   = false;
		m_pUIHandler->OnHandle(PAK_EVENT_UNLINK, 0, DATA_INDEX_GAMEDB);
		DEV_INFO(TF("[游戏服务器]连接游戏DB服务器断开"));
		LOG_INFO(m_FileLog, TF("[游戏服务器]连接游戏DB服务器断开"));
	}
	else if (krSocket == m_krListenZone) {
		m_krListenZone = nullptr;
		DEV_INFO(TF("[游戏服务器]监听地图服务器关闭"));
		LOG_INFO(m_FileLog, TF("[游戏服务器]监听地图服务器关闭"));
	}
	else if (krSocket == m_krListenGate) {
		m_krListenGate = nullptr;
		DEV_INFO(TF("[游戏服务器]监听网关服务器关闭"));
		LOG_INFO(m_FileLog, TF("[游戏服务器]监听网关服务器关闭"));
	}
	else { // 单个服务器断开
		switch (llLiveData) {
		case PAK_TYPE_ZONE:
			{
				ServerUnlink<SVR_ZONE_INDEX_MAP, DATA_INDEX_ZONE, INFOI_ZONE>(krSocket, m_ZoneSvrMap);
				DEV_INFO(TF("[游戏服务器]地图服务器[%p]断开"), krSocket);
				LOGV_INFO(m_FileLog, TF("游戏服务器]地图服务器[%p]断开"), krSocket);
			}
			break;
		case PAK_TYPE_GATE:
			{
				ServerUnlink<SVR_GATE_MAP, DATA_INDEX_GATE, INFOI_GATE>(krSocket, m_GateSvrMap);
				DEV_INFO(TF("[游戏服务器]网关服务器[%p]断开"), krSocket);
				LOGV_INFO(m_FileLog, TF("游戏服务器]网关服务器[%p]断开"), krSocket);
			}
			break;
		default:
			{
			}
		}
		m_ServerInfo.Decr();
	}
	return true;
}
Ejemplo n.º 16
0
bool CGameServer::SelectGame(CPAKLoginSelectGame* pSelect, LLong llParam)
{
	assert(pSelect->GetType() == PAK_TYPE_LOGIN);
	pSelect->SetType(PAK_TYPE_GAME);
	// 实际需要按电信或者网通线路PING值为参考来排序
	PSORT_RESULT pSortResult = m_SortChain.GetCur();
	if (pSortResult->lCount > 0) {
		Long lIndex = pSortResult->Index();
		if ((DataRef)m_pShareGateSvr == pSortResult->Sort[lIndex].drServer) {
			m_pShareGateSvr->OnShareRoutine(PAK_EVENT_LOGIN_SELECT_GAME, *pSelect, llParam);
		}
		else {
			m_NetworkPtr->SendTo(m_krUDPService, *pSelect, pSortResult->Sort[lIndex].Addr);
		}
		DEV_INFO(TF("[游戏服务器]选取第%d个网关服务器"), lIndex);
		return true;
	}
	return false;
}
int adv7525_i2c_read(struct i2c_client *client, u8 addr , u8 *buf , int length)
{
	struct i2c_adapter *adap = client->adapter;
	struct i2c_msg msg[2];

	msg[0].addr = client->addr;
	msg[0].flags = client->flags & I2C_M_TEN;
	msg[0].len = 1;
	msg[0].buf = &addr;
	msg[1].addr = client->addr;
	msg[1].flags = client->flags & I2C_M_TEN;
	msg[1].flags |= I2C_M_RD;
	msg[1].len = length;
	msg[1].buf = buf;

	if (i2c_transfer(adap, msg, 2) < 0) {
		DEV_INFO("%s: i2c read err\n", __func__);
		return -EBUSY;
	}
	return 0;
}
Ejemplo n.º 18
0
//--------------------------------------
bool CGameServer::OnShareRoutine(Int nEvent, CEventBase& EventRef, LLong llParam, CEventQueue::EVENT_TYPE)
{
	assert((m_pConfig->GetLoadServers() & (CServerConfig::CFG_DEFAULT_CENTER|CServerConfig::CFG_DEFAULT_GAMEDB|CServerConfig::CFG_DEFAULT_ZONE|CServerConfig::CFG_DEFAULT_GATE)) != 0);
	switch (nEvent) {
	case PAK_EVENT_LINK:
		{
			return OnShareLink(EventRef, llParam);
		}
		break;
	case PAK_EVENT_UPDATE:
		{
			return OnShareUpdate(EventRef, llParam);
		}
		break;
	//case PAK_EVENT_UNLINK: // 同进程服务器注销, 说明服务停止, 不需要处理
	//	break;
	case PAK_EVENT_GAME_ID:
		{
			PInt pId = reinterpret_cast<PInt>(llParam);
			*pId = (Int)m_ServerInfo.usId;
		}
		break;
	case PAK_EVENT_LOGIN_SELECT_GAME:
		{
			CPAKLoginSelectGame* pSelect = static_cast<CPAKLoginSelectGame*>(&EventRef);
			if (SelectGame(pSelect, llParam) == false) {
				pSelect->SetAck(LOGIN_ERROR_NONE_GATE);
				reinterpret_cast<ICommonServer*>(llParam)->OnShareRoutine(PAK_EVENT_LOGIN_SELECT_GAME, *pSelect);
				DEV_INFO(TF("[游戏服务器]同进程游戏服务器收到客户端选择游戏服务器请求, 但是没有网关服务器"));
			}
		}
		break;
	default:
		{
			LOGV_WARN(m_FileLog, TF("[游戏服务器]同进程服务器无法识别的信令包数据[event=%d]"), nEvent);
			assert(0);
		}
	}
	return true;
}
void adv7525_cec_init(void)
{
	int i;
	u16 phy_addr = hdmi_common_get_phy_addr();

	/* CEC Clock Timing Setting: 1.2MHz */
	for (i = 0; i < ARRAY_SIZE(cec_clk_table_1_2_mhz); i++)
		adv7525_write_reg(hclient_cec, cec_clk_table_1_2_mhz[i].reg_addr,
			cec_clk_table_1_2_mhz[i].reg_data);

	/* Initial cecdata structure */
	cecdata.logical_addr = hdmi_cec_get_logical_addr();
	cecdata.hdr_directly = cecdata.logical_addr << 4 | 0x0;
	cecdata.hdr_broadcast = cecdata.logical_addr << 4 | 0xf;
	cecdata.physical_addr[0] = (u8)(phy_addr >> 8);
	cecdata.physical_addr[1] = (u8)(phy_addr & 0x0f) ;
	DEV_INFO("logcal addr: 0x%x, physical addr: 0x%x\n", cecdata.logical_addr, phy_addr);

	/* CEC Rx Setting init */
	adv7525_write_reg(hclient_cec, 0x4a, 0);
	adv7525_write_reg(hclient_cec, 0x4c, (0xf << 4 | cecdata.logical_addr));
}
Ejemplo n.º 20
0
/* Change HDMI state */
static void change_hdmi_state(int online)
{
	if (!external_common_state)
		return;

	mutex_lock(&external_common_state_hpd_mutex);
	external_common_state->hpd_state = online;
	mutex_unlock(&external_common_state_hpd_mutex);

	if (!external_common_state->uevent_kobj)
		return;

	if (online) {
		kobject_uevent(external_common_state->uevent_kobj,
			KOBJ_ONLINE);
		switch_set_state(&external_common_state->sdev, 1);
	} else {
		kobject_uevent(external_common_state->uevent_kobj,
			KOBJ_OFFLINE);
		switch_set_state(&external_common_state->sdev, 0);
	}
	DEV_INFO("adv7520_uevent: %d [suspend# %d]\n", online, suspend_count);
}
Ejemplo n.º 21
0
static void adv7520_close_hdcp_link(void)
{
	if (!external_common_state->hdcp_active && !hdcp_activating)
		return;

	DEV_INFO("HDCP: Close link\n");

	reg[0xD5] = adv7520_read_reg(hclient, 0xD5);
	reg[0xD5] &= 0xFE;
	adv7520_write_reg(hclient, 0xD5, (u8)reg[0xD5]);

	reg[0x16] = adv7520_read_reg(hclient, 0x16);
	reg[0x16] &= 0xFE;
	adv7520_write_reg(hclient, 0x16, (u8)reg[0x16]);

	/* UnMute Audio */
	adv7520_write_reg(hclient, 0x0C, (u8)0x84);

	external_common_state->hdcp_active = FALSE;
	mutex_lock(&hdcp_state_mutex);
	hdcp_activating = FALSE;
	mutex_unlock(&hdcp_state_mutex);
}
Ejemplo n.º 22
0
static void hdmi_tx_hpd_state_work(struct work_struct *work)
{
	u32 hpd_state = false;
	struct hdmi_tx_ctrl *hdmi_ctrl = NULL;
	struct hdmi_tx_io_data *io = NULL;

	hdmi_ctrl = container_of(work, struct hdmi_tx_ctrl, hpd_state_work);
	if (!hdmi_ctrl || !hdmi_ctrl->hpd_initialized) {
		DEV_DBG("%s: invalid input\n", __func__);
		return;
	}

	io = &hdmi_ctrl->pdata.io[HDMI_TX_CORE_IO];
	DEV_DBG("%s: Got HPD interrupt\n", __func__);

	hpd_state = (HDMI_REG_R(io->base, HDMI_HPD_INT_STATUS) & BIT(1)) >> 1;
	mutex_lock(&hdmi_ctrl->mutex);
	if ((hdmi_ctrl->hpd_prev_state != hdmi_ctrl->hpd_state) ||
		(hdmi_ctrl->hpd_state != hpd_state)) {

		hdmi_ctrl->hpd_state = hpd_state;
		hdmi_ctrl->hpd_prev_state = hdmi_ctrl->hpd_state;
		hdmi_ctrl->hpd_stable = 0;

		DEV_DBG("%s: state not stable yet, wait again (%d|%d|%d)\n",
			__func__, hdmi_ctrl->hpd_prev_state,
			hdmi_ctrl->hpd_state, hpd_state);

		mutex_unlock(&hdmi_ctrl->mutex);

		mod_timer(&hdmi_ctrl->hpd_state_timer, jiffies + HZ/2);

		return;
	}

	if (hdmi_ctrl->hpd_stable) {
		mutex_unlock(&hdmi_ctrl->mutex);
		DEV_DBG("%s: no more timer, depending on IRQ now\n",
			__func__);
		return;
	}

	hdmi_ctrl->hpd_stable = 1;
	DEV_INFO("HDMI HPD: event detected\n");

	/*
	 *todo: Revisit cable chg detected condition when HPD support is ready
	 */
	hdmi_ctrl->hpd_cable_chg_detected = false;
	mutex_unlock(&hdmi_ctrl->mutex);

	if (hpd_state) {
		DEV_INFO("HDMI HPD: sense CONNECTED: send ONLINE\n");
		kobject_uevent(hdmi_ctrl->kobj, KOBJ_ONLINE);
		switch_set_state(&hdmi_ctrl->sdev, 1);
		DEV_INFO("%s: Hdmi state switch to %d\n", __func__,
			hdmi_ctrl->sdev.state);
	} else {
		DEV_INFO("HDMI HPD: sense DISCONNECTED: send OFFLINE\n");
		kobject_uevent(hdmi_ctrl->kobj, KOBJ_OFFLINE);
		switch_set_state(&hdmi_ctrl->sdev, 0);
		DEV_INFO("%s: Hdmi state switch to %d\n", __func__,
			hdmi_ctrl->sdev.state);
	}

	/* Set IRQ for HPD */
	HDMI_REG_W(io->base, HDMI_HPD_INT_CTRL, 4 | (hpd_state ? 0 : 2));
} /* hdmi_tx_hpd_state_work */
void adv7525_cec_rx_handle(u8 *rxbuf)
{
	u8 txbuf[16] = {0};
	int tx_length = 0;

	DEV_INFO("%s: Opcode=0x%x, Data1=0x%x\n", __func__, rxbuf[1], rxbuf[2]);
	switch (rxbuf[1]) {
	case CEC_OPCODE_USER_CONTROL_PRESSED:
		if (rxbuf[2])
			input_report_key(dd->input, rxbuf[2], 1);
		else
			input_report_key(dd->input, 0x2b, 1);	/* Select key */
	break;

	case CEC_OPCODE_USER_CONTROL_RELEASED:
		if (rxbuf[2])
			input_report_key(dd->input, rxbuf[2], 0);
		else
			input_report_key(dd->input, 0x2b, 0);
	break;

	case CEC_OPCODE_PLAY:
		switch (rxbuf[2]) {
		case 0x24:
		case 0x25:
			input_report_key(dd->input, 0x46, 1);
			input_report_key(dd->input, 0x46, 0);
		break;

		default:
		break;
		}
	break;

	case CEC_OPCODE_DECK_CONTROL:
		switch (rxbuf[2]) {
		case 0x1:
			input_report_key(dd->input, 0x49, 1);
			input_report_key(dd->input, 0x49, 0);
		break;
		case 0x2:
			input_report_key(dd->input, 0x48, 1);
			input_report_key(dd->input, 0x48, 0);
		break;
		case 0x3: /* stop */
			input_report_key(dd->input, 0x46, 1);
			input_report_key(dd->input, 0x46, 0);
		break;
		default:
		break;
		}
	break;

	case CEC_OPCODE_GIVE_OSD_NAME:
		txbuf[1] = cecdata.hdr_directly;
		txbuf[2] = CEC_OPCODE_SET_OSD_NAME;
		txbuf[3] = 'A';
		txbuf[4] = 'c';
		txbuf[5] = 'e';
		txbuf[6] = 'r';
		txbuf[7] = ' ';
		txbuf[8] = 'S';
		txbuf[9] = '3';
		txbuf[10] = '0';
		txbuf[11] = '0';
		tx_length = 11;
	break;

	case CEC_OPCODE_GIVE_DEVICE_VENDOR_ID:
		txbuf[1] = cecdata.hdr_broadcast;
		txbuf[2] = CEC_OPCODE_DEVICE_VENDOR_ID;
		txbuf[3] = 0x00;
		txbuf[4] = 0x00;
		txbuf[5] = 0xE2;
		tx_length = 5;
	break;

	case CEC_OPCODE_GIVE_DEVICE_POWER_STATUS:
		txbuf[1] = cecdata.hdr_directly;
		txbuf[2] = CEC_OPCODE_REPORT_POWER_STATUS;
		txbuf[3] = 0x00;
		tx_length = 3;
	break;

	case CEC_OPCODE_GET_CEC_VERSION:
		txbuf[1] = cecdata.hdr_directly;
		txbuf[2] = CEC_OPCODE_CEC_VERSION;
		txbuf[3] = 0x04;
		tx_length = 3;
	break;

	case CEC_OPCODE_SET_STREAM_PATH:
	case CEC_OPCODE_REQUEST_ACTIVE_SOURCE:
		txbuf[1] = cecdata.hdr_broadcast;
		txbuf[2] = CEC_OPCODE_ACTIVE_SOURCE;
		txbuf[3] = cecdata.physical_addr[0];
		txbuf[4] = cecdata.physical_addr[1];
		tx_length = 4;
	break;

	case CEC_OPCODE_GIVE_PHYSICAL_ADDRESS:
		txbuf[1] = cecdata.hdr_broadcast;
		txbuf[2] = CEC_OPCODE_REPORT_PHYSICAL_ADDRESS;
		txbuf[3] = cecdata.physical_addr[0];
		txbuf[4] = cecdata.physical_addr[1];
		txbuf[5] = type_playback_device;
		tx_length = 5;
	break;

	case CEC_OPCODE_GIVE_DECK_STATUS:
		txbuf[1] = cecdata.hdr_directly;
		txbuf[2] = CEC_OPCODE_DECK_STATUS;
		txbuf[3] = 0x01;
		tx_length = 3;
	break;

	case CEC_OPCODE_MENU_REQUEST:
		txbuf[1] = cecdata.hdr_directly;
		txbuf[2] = CEC_OPCODE_MENU_STATUS;
		txbuf[3] = 0x01;
		tx_length = 3;
	break;

	default:
	break;
	}

	if (tx_length != 0) {
		adv7525_i2c_write(hclient_cec, txbuf, tx_length+1);
		adv7525_write_reg(hclient_cec, 0x10, tx_length);
		adv7525_write_reg(hclient_cec, 0x11, 0x1);
	}
}