Exemple #1
0
static void disable_unused_touchscreen(void *unused)
{
	struct device *i2c0 = PCH_DEV_I2C0;
	struct bus *i2c_slaves = i2c0->link_list;
	struct device *slave = i2c_slaves->children;
	char touchscreen_hid[9] = CONFIG_TOUCHSCREEN_HID;
	struct drivers_i2c_hid_config *info;

	/* Look for VPD key that indicates which touchscreen is present */
	if (CONFIG(VPD) &&
	    !vpd_gets(TOUCHSCREEN_VPD_KEY, touchscreen_hid,
		      ARRAY_SIZE(touchscreen_hid), VPD_ANY))
		printk(BIOS_INFO, "%s: VPD key '%s' not found, default to %s\n",
		       __func__, TOUCHSCREEN_VPD_KEY, touchscreen_hid);

	/* Go through all I2C slave devices on this bus */
	while (slave) {
		/* Find all the I2C slaves with the matching address */
		if (slave->path.type == DEVICE_PATH_I2C &&
		    slave->path.i2c.device == TOUCHSCREEN_I2C_ADDR) {
			info = slave->chip_info;
			/* Disable all devices except the matching HID */
			if (strncmp(info->generic.hid, touchscreen_hid,
				    ARRAY_SIZE(touchscreen_hid))) {
				printk(BIOS_INFO, "%s: Disable %s\n", __func__,
				       info->generic.hid);
				slave->enabled = 0;
			} else {
				printk(BIOS_INFO, "%s: Enable %s\n", __func__,
				       info->generic.hid);
			}
		}
		slave = slave->sibling;
	}
}
Exemple #2
0
/* Retrieve the wifi SAR limits data from VPD and decode it

For VPD: key,value pair is in this format
"wifi_sar"=[<WRDD><EWRD>][WGDS]

WIFI SAR data in CBFS file is expected in same format: [<WRDD><EWRD>][WGDS]

[<WRDD><EWRD>] = NUM_SAR_LIMITS * BYTES_PER_SAR_LIMIT bytes.
[WGDS]=[WGDS_VERSION][WGDS_DATA]

For [WGDS_VERSION] 0x00,
[WGDS_DATA] = [GROUP#0][GROUP#1][GROUP#2]

[GROUP#<i>] =
	[2.4Ghz – Max Allowed][2.4Ghz – Chain A Offset]
	[2.4Ghz – Chain B Offset][5Ghz – Max Allowed]
	[5Ghz – Chain A Offset][5Ghz – Chain B Offset]

[GROUP#0] is for FCC
[GROUP#1] is for Europe/Japan
[GROUP#2] is for ROW

*/
int get_wifi_sar_limits(struct wifi_sar_limits *sar_limits)
{
	const char *wifi_sar_limit_key = CROS_VPD_WIFI_SAR_NAME;
	/* vpd_gets() reads in one less than size characters from the VPD
	 * with a terminating null byte ('\0') stored as the last character into
	 * the buffer, thus the increasing by 1 for buffer_size. */
	const size_t buffer_size = (sizeof(struct wifi_sar_limits) /
					sizeof(uint8_t)) * 2 + 1;
	char wifi_sar_limit_str[buffer_size];
	uint8_t bin_buffer[sizeof(struct wifi_sar_limits)];
	size_t sar_cbfs_len, sar_expected_len, bin_buff_adjusted_size;

	/* keep it backward compatible. Some older platform are shipping
	   without GEO SAR and so older wifi_sar VPD key */

	sar_expected_len = buffer_size;
	bin_buff_adjusted_size = sizeof(struct wifi_sar_limits);

	if (!IS_ENABLED(CONFIG_GEO_SAR_ENABLE)) {
		sar_expected_len = buffer_size -
					sizeof(struct wifi_sar_delta_table) *
					sizeof(uint8_t) * 2;
		bin_buff_adjusted_size = sizeof(struct wifi_sar_limits) -
					 sizeof(struct wifi_sar_delta_table);
	}

	/* Try to read the SAR limit entry from VPD */
	if (!vpd_gets(wifi_sar_limit_key, wifi_sar_limit_str,
							 buffer_size, VPD_ANY)) {
		printk(BIOS_ERR, "Error: Could not locate '%s' in VPD.\n",
				wifi_sar_limit_key);

		if (!IS_ENABLED(CONFIG_WIFI_SAR_CBFS))
			return -1;

		printk(BIOS_DEBUG, "Checking CBFS for default SAR values\n");

		sar_cbfs_len = load_sar_file_from_cbfs(
					(void *) wifi_sar_limit_str,
						sar_expected_len);

		if (sar_cbfs_len != sar_expected_len) {
			printk(BIOS_ERR, "%s has bad len in CBFS\n",
					WIFI_SAR_CBFS_FILENAME);
			return -1;
		}
	} else {
		/* VPD key "wifi_sar" found. strlen is checked with addition of
		 * 1 as we have created buffer size 1 char larger for the reason
		 * mentioned at start of this function itself */
		if (strlen(wifi_sar_limit_str) + 1 != sar_expected_len) {
			printk(BIOS_ERR, "WIFI SAR key has bad len in VPD\n");
			return -1;
		}
	}

	/* Decode the heximal encoded string to binary values */
	if (hexstrtobin(wifi_sar_limit_str, bin_buffer, bin_buff_adjusted_size)
			< bin_buff_adjusted_size) {
		printk(BIOS_ERR, "Error: wifi_sar contains non-hex value!\n");
		return -1;
	}

	memset(sar_limits, 0, sizeof(*sar_limits));
	memcpy(sar_limits, bin_buffer, bin_buff_adjusted_size);
	return 0;
}