static int adv7520_power_on(struct platform_device *pdev) { unsigned long reg0x41 = 0xff, reg0x42 = 0xff, reg0xaf = 0xff; bool hpd_set = TRUE; if (!power_on) { reg0x42 = adv7520_read_reg(hclient, 0x42); if (!test_bit(6, ®0x42)) hpd_set = FALSE; } if (hpd_set) { reg0x41 = adv7520_read_reg(hclient, 0x41); reg0xaf = adv7520_read_reg(hclient, 0xaf); if (!power_on) { clear_bit(6, ®0x41); set_bit(1, ®0xaf); adv7520_write_reg(hclient, 0x41, (u8)reg0x41); adv7520_write_reg(hclient, 0xaf, (u8)reg0xaf); power_on = TRUE ; } } return 0; }
/* Power ON/OFF ADV7520 chip */ static int adv7520_power_on(struct platform_device *pdev) { unsigned long reg0x41 = 0xff, reg0x42 = 0xff, reg0xaf = 0xff; bool hpd_set = TRUE; /* Attempting to enable power */ if (!power_on) { /* Get the register holding the HPD bit, this must be set before power up. */ reg0x42 = adv7520_read_reg(hclient, 0x42); if (!test_bit(6, ®0x42)) hpd_set = FALSE; } if (hpd_set) { /* Get the current register holding the power bit. */ reg0x41 = adv7520_read_reg(hclient, 0x41); reg0xaf = adv7520_read_reg(hclient, 0xaf); /* Enable power */ if (!power_on) { /* Clear the power down bit to enable power. */ clear_bit(6, ®0x41); /* Set the HDMI select bit. */ set_bit(1, ®0xaf); adv7520_write_reg(hclient, 0x41, (u8)reg0x41); adv7520_write_reg(hclient, 0xaf, (u8)reg0xaf); power_on = TRUE ; } } return 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); }
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 adv7520_close_hdcp_link(void) { reg[0xD5] = adv7520_read_reg(hclient, 0xD5); /* reg[0xD5] &= 0xFE; */ reg[0xD5] = 0xFE; adv7520_write_reg(hclient, 0xD5, (u8)reg[0xD5]); reg[0x16] = adv7520_read_reg(hclient, 0x16); /* reg[0x16] &= 0xFE; */ reg[0x16] = 0xFE; adv7520_write_reg(hclient, 0x16, (u8)reg[0x16]); /* Mute Audio */ reg[0x0C] = adv7520_read_reg(hclient, 0x0C); /* reg[0x0C] &= 0xC3; */ reg[0x0C] = 0xC3; adv7520_write_reg(hclient, 0x0C, (u8)reg[0x0C]); printk(KERN_INFO"\n Putting TV Audio to Mute\n"); }
static int adv7520_power_off(struct platform_device *pdev) { unsigned long reg0x41 = 0xff; if (power_on) { reg0x41 = adv7520_read_reg(hclient, 0x41); /* Power down the whole chip,except I2C,HPD interrupt */ reg0x41 = adv7520_read_reg(hclient, 0x41); set_bit(6, ®0x41); adv7520_write_reg(hclient, 0x41, (u8)reg0x41); power_on = FALSE ; } return 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); }
static int adv7520_power_off(struct platform_device *pdev) { unsigned long reg0x41 = 0xff; if (power_on) { reg0x41 = adv7520_read_reg(hclient, 0x41); reg0x41 = adv7520_read_reg(hclient, 0x41); set_bit(6, ®0x41); adv7520_write_reg(hclient, 0x41, (u8)reg0x41); power_on = FALSE ; } return 0; }
static void adv7520_hdcp_enable(struct work_struct *work) { printk(KERN_INFO "Starting HDCP "); /* Set HDCP request Bit */ reg[0xAF] = adv7520_read_reg(hclient, 0xAF); reg[0xAF] |= 0x90; adv7520_write_reg(hclient, 0xaf, (u8)reg[0xaf]); reg[0xAF] = adv7520_read_reg(hclient, 0xAF); printk(KERN_INFO"\n HDCP request reg[0xaf] is %x\n" , reg[0xaf]); msleep(20); /* 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); printk(KERN_INFO "\n BKSV[1] is %x\n ", reg[0xbf]); printk(KERN_INFO "\n BKSV[2] is %x\n ", reg[0xc0]); printk(KERN_INFO "\n BKSV[3] is %x\n ", reg[0xc1]); printk(KERN_INFO "\n BKSV[4] is %x\n ", reg[0xc2]); printk(KERN_INFO "\n BKSV[5] is %x\n ", reg[0xc3]); /* Is SINK repeater */ reg[0xBE] = adv7520_read_reg(hclient, 0xBE); printk(KERN_INFO"\n Sink Repeater reg is %x\n", reg[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 */ return; } msleep(20); reg[0xB8] = adv7520_read_reg(hclient, 0xB8); printk(KERN_INFO "\n HDCP Status reg is reg[0xB8 is %x\n", reg[0xb8]); if ((reg[0xb8] & 0x40) || (reg[0xb8] & 0x10)) { printk(KERN_INFO "Closing the HDMI link"); adv7520_close_hdcp_link(); } }
/* AV7520 chip specific initialization */ static void adv7520_enable(void) { /* Initialize the variables used to read/write the ADV7520 chip. */ memset(®, 0xff, sizeof(reg)); /* Get the values from the "Fixed Registers That Must Be Set". */ reg[0x98] = adv7520_read_reg(hclient, 0x98); reg[0x9c] = adv7520_read_reg(hclient, 0x9c); reg[0x9d] = adv7520_read_reg(hclient, 0x9d); reg[0xa2] = adv7520_read_reg(hclient, 0xa2); reg[0xa3] = adv7520_read_reg(hclient, 0xa3); reg[0xde] = adv7520_read_reg(hclient, 0xde); /* EDID Registers */ reg[0x43] = adv7520_read_reg(hclient, 0x43); reg[0xc8] = adv7520_read_reg(hclient, 0xc8); /* Get the "HDMI/DVI Selection" register. */ reg[0xaf] = adv7520_read_reg(hclient, 0xaf); /* Hard coded values provided by ADV7520 data sheet. */ reg[0x98] = 0x03; reg[0x9c] = 0x38; reg[0x9d] = 0x61 ; reg[0xa2] = 0x94; reg[0xa3] = 0x94; reg[0xde] = 0x88; /* Set the HDMI select bit. */ reg[0xaf] |= 0x16; /* Set the audio related registers. */ reg[0x01] = 0x00; reg[0x02] = 0x2d; reg[0x03] = 0x80; reg[0x0a] = 0x4d ; reg[0x0b] = 0x0e ; reg[0x0c] = 0x84 ; reg[0x0d] = 0x10 ; reg[0x12] = 0x00 ; reg[0x14] = 0x00 ; reg[0x15] = 0x20 ; reg[0x44] = 0x79 ; reg[0x73] = 0x1 ; reg[0x76] = 0x00 ; /* Set 720p display related registers */ reg[0x16] = 0x00; reg[0x18] = 0x46; reg[0x55] = 0x00; reg[0xba] = 0x60; reg[0x3c] = 0x04; /* Set the values from the "Fixed Registers That Must Be Set". */ adv7520_write_reg(hclient, 0x98, reg[0x98]); adv7520_write_reg(hclient, 0x9c, reg[0x9c]); adv7520_write_reg(hclient, 0x9d, reg[0x9d]); adv7520_write_reg(hclient, 0xa2, reg[0xa2]); adv7520_write_reg(hclient, 0xa3, reg[0xa3]); adv7520_write_reg(hclient, 0xde, reg[0xde]); /* Set the "HDMI/DVI Selection" register. */ adv7520_write_reg(hclient, 0xaf, reg[0xaf]); /* Set EDID Monitor address */ reg[0x43] = ADV7520_EDIDI2CSLAVEADDRESS ; adv7520_write_reg(hclient, 0x43, reg[0x43]); /* Enable the i2s audio input. */ adv7520_write_reg(hclient, 0x01, reg[0x01]); adv7520_write_reg(hclient, 0x02, reg[0x02]); adv7520_write_reg(hclient, 0x03, reg[0x03]); adv7520_write_reg(hclient, 0x0a, reg[0x0a]); adv7520_write_reg(hclient, 0x0b, reg[0x0b]); adv7520_write_reg(hclient, 0x0c, reg[0x0c]); adv7520_write_reg(hclient, 0x0d, reg[0x0d]); adv7520_write_reg(hclient, 0x12, reg[0x12]); adv7520_write_reg(hclient, 0x14, reg[0x14]); adv7520_write_reg(hclient, 0x15, reg[0x15]); adv7520_write_reg(hclient, 0x44, reg[0x44]); adv7520_write_reg(hclient, 0x73, reg[0x73]); adv7520_write_reg(hclient, 0x76, reg[0x76]); /* Enable 720p display */ adv7520_write_reg(hclient, 0x16, reg[0x16]); adv7520_write_reg(hclient, 0x18, reg[0x18]); adv7520_write_reg(hclient, 0x55, reg[0x55]); adv7520_write_reg(hclient, 0xba, reg[0xba]); adv7520_write_reg(hclient, 0x3c, reg[0x3c]); }
static void adv7520_enable(void) { memset(®, 0xff, sizeof(reg)); reg[0x98] = adv7520_read_reg(hclient, 0x98); reg[0x9c] = adv7520_read_reg(hclient, 0x9c); reg[0x9d] = adv7520_read_reg(hclient, 0x9d); reg[0xa2] = adv7520_read_reg(hclient, 0xa2); reg[0xa3] = adv7520_read_reg(hclient, 0xa3); reg[0xde] = adv7520_read_reg(hclient, 0xde); reg[0x43] = adv7520_read_reg(hclient, 0x43); reg[0xc8] = adv7520_read_reg(hclient, 0xc8); reg[0xaf] = adv7520_read_reg(hclient, 0xaf); reg[0x98] = 0x03; reg[0x9c] = 0x38; reg[0x9d] = 0x61 ; reg[0xa2] = 0x94; reg[0xa3] = 0x94; reg[0xde] = 0x88; reg[0xaf] |= 0x16; reg[0x01] = 0x00; reg[0x02] = 0x2d; reg[0x03] = 0x80; reg[0x0a] = 0x4d ; reg[0x0b] = 0x0e ; reg[0x0c] = 0x84 ; reg[0x0d] = 0x10 ; reg[0x12] = 0x00 ; reg[0x14] = 0x00 ; reg[0x15] = 0x20 ; reg[0x44] = 0x79 ; reg[0x73] = 0x1 ; reg[0x76] = 0x00 ; reg[0x16] = 0x00; reg[0x18] = 0x46; reg[0x55] = 0x00; reg[0xba] = 0x60; reg[0x3c] = 0x04; adv7520_write_reg(hclient, 0x98, reg[0x98]); adv7520_write_reg(hclient, 0x9c, reg[0x9c]); adv7520_write_reg(hclient, 0x9d, reg[0x9d]); adv7520_write_reg(hclient, 0xa2, reg[0xa2]); adv7520_write_reg(hclient, 0xa3, reg[0xa3]); adv7520_write_reg(hclient, 0xde, reg[0xde]); adv7520_write_reg(hclient, 0xaf, reg[0xaf]); reg[0x43] = ADV7520_EDIDI2CSLAVEADDRESS ; adv7520_write_reg(hclient, 0x43, reg[0x43]); adv7520_write_reg(hclient, 0x01, reg[0x01]); adv7520_write_reg(hclient, 0x02, reg[0x02]); adv7520_write_reg(hclient, 0x03, reg[0x03]); adv7520_write_reg(hclient, 0x0a, reg[0x0a]); adv7520_write_reg(hclient, 0x0b, reg[0x0b]); adv7520_write_reg(hclient, 0x0c, reg[0x0c]); adv7520_write_reg(hclient, 0x0d, reg[0x0d]); adv7520_write_reg(hclient, 0x12, reg[0x12]); adv7520_write_reg(hclient, 0x14, reg[0x14]); adv7520_write_reg(hclient, 0x15, reg[0x15]); adv7520_write_reg(hclient, 0x44, reg[0x44]); adv7520_write_reg(hclient, 0x73, reg[0x73]); adv7520_write_reg(hclient, 0x76, reg[0x76]); adv7520_write_reg(hclient, 0x16, reg[0x16]); adv7520_write_reg(hclient, 0x18, reg[0x18]); adv7520_write_reg(hclient, 0x55, reg[0x55]); adv7520_write_reg(hclient, 0xba, reg[0xba]); adv7520_write_reg(hclient, 0x3c, reg[0x3c]); }