Received: by 2002:a25:1985:0:0:0:0:0 with SMTP id 127csp1777576ybz; Sun, 26 Apr 2020 04:05:15 -0700 (PDT) X-Google-Smtp-Source: APiQypJNIp65v3sM+J7qZYmxqfojgQiTodZziuh5bNvAXPOXiKpzW549jmtl/ePZMqKH+Q3BF7JG X-Received: by 2002:a17:906:38c:: with SMTP id b12mr14697590eja.332.1587899115212; Sun, 26 Apr 2020 04:05:15 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1587899115; cv=none; d=google.com; s=arc-20160816; b=otXSkLlpEyIbQXv9qAqCWMl1c5twgH6efzt6fCBMb5/+gqL7xzzvj60nZ35VrWP5KF 1AgR4s7Z6507jGMpQQnkcF4srWnwATp9Tf8nK0XBdC235t3FBNpDDKnPjEvoEozt+nGl f3Ksljyc3KffkklT4Do0GhPgA0v2MLS7ztUMa2s20ctOL+tPlxMXHQJKCTqDclQ83ovH GP2AAuoQrcXOOaEy5KYwCGaHDUnNFtDNoppSrLQTjuF7B2kLSI/Een5710UgNbT72IZn iVDSlfokwPddR23GbBnjpxXV7mYn/jL/StlGwTaNGErwHW/J+ohYq/E8ZQI7cVHS6+Ym 7P3g== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:sender:content-transfer-encoding:mime-version :references:in-reply-to:message-id:date:subject:cc:to:from :dkim-signature; bh=Ia70Ai/6NHdFWgYbYmkiuqWOyDh2dovsyzqZrEtEQlk=; b=dgvJSJISo3HN1/eOH7iyXEv5XbIV0AEJSqnHYBhLkHq2h9/6ORmdgpYfZHy9xQV3rw OxSGaUWYkvMGd9KbGDksW1dbVHuPSKlD1/VlFc3D6+Tlk0hdIR2MX859S1k6NVNuNcac t+PnGOh7AlLHuXGGX4mRkVjIWiHJlUA+FBnoQeSTrbEoniQNVqgQamUr2PGaMK9/+xsQ L5w92RuiJwDrQMlEo5ST6uRr7bokusJph9VgWSUJxgT5t2p2RYcsjQiiB+ciiKvh4HA0 7bPROh+LbBfPfcXET1XqB+HrHNjXJEKSFa3T2jMwYudOyrPfdxnQJlN5IzFzDZ0mxF4i pRNA== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=I7rlGyny; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Return-Path: Received: from vger.kernel.org (vger.kernel.org. [23.128.96.18]) by mx.google.com with ESMTP id i63si5954550edd.601.2020.04.26.04.04.52; Sun, 26 Apr 2020 04:05:15 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) client-ip=23.128.96.18; Authentication-Results: mx.google.com; dkim=pass header.i=@redhat.com header.s=mimecast20190719 header.b=I7rlGyny; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 23.128.96.18 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=NONE sp=NONE dis=NONE) header.from=redhat.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726229AbgDZLD1 (ORCPT + 99 others); Sun, 26 Apr 2020 07:03:27 -0400 Received: from us-smtp-2.mimecast.com ([205.139.110.61]:27972 "EHLO us-smtp-delivery-1.mimecast.com" rhost-flags-OK-OK-OK-FAIL) by vger.kernel.org with ESMTP id S1726154AbgDZLDY (ORCPT ); Sun, 26 Apr 2020 07:03:24 -0400 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1587899003; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=Ia70Ai/6NHdFWgYbYmkiuqWOyDh2dovsyzqZrEtEQlk=; b=I7rlGynyQI86WW7eMRdndv2lODXC8/YshA3dpV5WjHVWrHaa+U31wEqvwaWVBzJcHRnZyq G5UoLOSEAJ9+Q//SpM2MLCHhN5D8uuHxVuGi9IFQ2fOgii3SGS7ID16wABeeaWXLFKgkwk /j7JFU6NCG79cfN6jqB2bBeT0h/VfxE= Received: from mimecast-mx01.redhat.com (mimecast-mx01.redhat.com [209.132.183.4]) (Using TLS) by relay.mimecast.com with ESMTP id us-mta-512-W5Bp-2zlOUK7Il4fkM32_g-1; Sun, 26 Apr 2020 07:03:21 -0400 X-MC-Unique: W5Bp-2zlOUK7Il4fkM32_g-1 Received: from smtp.corp.redhat.com (int-mx07.intmail.prod.int.phx2.redhat.com [10.5.11.22]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mimecast-mx01.redhat.com (Postfix) with ESMTPS id DFC651895870; Sun, 26 Apr 2020 11:03:19 +0000 (UTC) Received: from x1.localdomain.com (ovpn-112-32.ams2.redhat.com [10.36.112.32]) by smtp.corp.redhat.com (Postfix) with ESMTP id 5673610013A1; Sun, 26 Apr 2020 11:03:17 +0000 (UTC) From: Hans de Goede To: "Rafael J . Wysocki" , Len Brown , Darren Hart , Andy Shevchenko , Kevin Tsai , Jonathan Cameron Cc: Hans de Goede , linux-acpi@vger.kernel.org, platform-driver-x86@vger.kernel.org, linux-kernel@vger.kernel.org, Hartmut Knaack , Lars-Peter Clausen , Peter Meerwald-Stadler , linux-iio@vger.kernel.org Subject: [PATCH 7/8] iio: light: cm32181: Add support for parsing CPM0 and CPM1 ACPI tables Date: Sun, 26 Apr 2020 13:02:55 +0200 Message-Id: <20200426110256.218186-7-hdegoede@redhat.com> In-Reply-To: <20200426110256.218186-1-hdegoede@redhat.com> References: <20200426110256.218186-1-hdegoede@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.84 on 10.5.11.22 Content-Transfer-Encoding: quoted-printable Sender: linux-kernel-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org On ACPI based systems the CPLM3218 ACPI device node describing the CM3218[1] sensor typically will have some extra tables with register init values for initializing the sensor and calibration info. This is based on a newer version of cm32181.c, with a copyright of: * Copyright (C) 2014 Capella Microsystems Inc. * Author: Kevin Tsai * * This program is free software; you can redistribute it and/or modify i= t * under the terms of the GNU General Public License version 2, as publis= hed * by the Free Software Foundation. Which is floating around on the net in various places, but the changes from this newer version never made it upstream. This was tested on the following models: Acer Switch 10 SW5-012 (CM32181) Asus T100TA (CM3218), Asus T100CHI (CM3218) and HP X2 10-n000nd (CM32181)= . Signed-off-by: Hans de Goede --- drivers/iio/light/cm32181.c | 98 +++++++++++++++++++++++++++++++++++++ 1 file changed, 98 insertions(+) diff --git a/drivers/iio/light/cm32181.c b/drivers/iio/light/cm32181.c index e5674d4a8143..878fc13632d8 100644 --- a/drivers/iio/light/cm32181.c +++ b/drivers/iio/light/cm32181.c @@ -4,6 +4,7 @@ * Author: Kevin Tsai */ =20 +#include #include #include #include @@ -53,6 +54,15 @@ =20 #define SMBUS_ALERT_RESPONSE_ADDRESS 0x0c =20 +/* CPM0 Index 0: device-id (3218 or 32181), 1: Unknown, 2: init_regs_bit= map */ +#define CPM0_REGS_BITMAP 2 +#define CPM0_HEADER_SIZE 3 + +/* CPM1 Index 0: lux_per_bit, 1: calibscale, 2: resolution (100000) */ +#define CPM1_LUX_PER_BIT 0 +#define CPM1_CALIBSCALE 1 +#define CPM1_SIZE 3 + /* CM3218 Family */ static const int cm3218_als_it_bits[] =3D { 0, 1, 2, 3 }; static const int cm3218_als_it_values[] =3D { 100000, 200000, 400000, 80= 0000 }; @@ -76,6 +86,56 @@ struct cm32181_chip { const int *als_it_values; }; =20 +static int cm32181_read_als_it(struct cm32181_chip *cm32181, int *val2); + +#ifdef CONFIG_ACPI +/** + * cm32181_acpi_get_cpm() - Get CPM object from ACPI + * @client pointer of struct i2c_client. + * @obj_name pointer of ACPI object name. + * @count maximum size of return array. + * @vals pointer of array for return elements. + * + * Convert ACPI CPM table to array. + * + * Return: -ENODEV for fail. Otherwise is number of elements. + */ +static int cm32181_acpi_get_cpm(struct i2c_client *client, char *obj_nam= e, + u64 *values, int count) +{ + struct acpi_buffer buffer =3D { ACPI_ALLOCATE_BUFFER, NULL }; + union acpi_object *cpm, *elem; + acpi_handle handle; + acpi_status status; + int i; + + handle =3D ACPI_HANDLE(&client->dev); + if (!handle) + return -ENODEV; + + status =3D acpi_evaluate_object(handle, obj_name, NULL, &buffer); + if (ACPI_FAILURE(status)) { + dev_err(&client->dev, "object %s not found\n", obj_name); + return -ENODEV; + } + + cpm =3D buffer.pointer; + if (cpm->package.count > count) + dev_warn(&client->dev, "%s table contains %d values, only using first = %d values\n", + obj_name, cpm->package.count, count); + + count =3D min_t(int, cpm->package.count, count); + for (i =3D 0; i < count; i++) { + elem =3D &(cpm->package.elements[i]); + values[i] =3D elem->integer.value; + } + + kfree(buffer.pointer); + + return count; +} +#endif /* CONFIG_ACPI */ + /** * cm32181_reg_init() - Initialize CM32181 registers * @cm32181: pointer of struct cm32181. @@ -121,6 +181,44 @@ static int cm32181_reg_init(struct cm32181_chip *cm3= 2181) cm32181->lux_per_bit =3D CM32181_LUX_PER_BIT; cm32181->lux_per_bit_base_it =3D CM32181_LUX_PER_BIT_BASE_IT; =20 +#ifdef CONFIG_ACPI + if (ACPI_HANDLE(&client->dev)) { + u64 values[CPM0_HEADER_SIZE + CM32181_CONF_REG_NUM]; + int count; + + count =3D cm32181_acpi_get_cpm(client, "CPM0", + values, ARRAY_SIZE(values)); + if (count <=3D CPM0_HEADER_SIZE) + goto cpm_parsing_done; + + count -=3D CPM0_HEADER_SIZE; + + cm32181->init_regs_bitmap =3D values[CPM0_REGS_BITMAP]; + cm32181->init_regs_bitmap &=3D GENMASK(count - 1, 0); + for (i =3D 0; i < count; i++) { + if (cm32181->init_regs_bitmap & BIT(i)) + cm32181->conf_regs[i] =3D + values[CPM0_HEADER_SIZE + i]; + } + + count =3D cm32181_acpi_get_cpm(client, "CPM1", + values, ARRAY_SIZE(values)); + if (count !=3D CPM1_SIZE) + goto cpm_parsing_done; + + cm32181->lux_per_bit =3D values[CPM1_LUX_PER_BIT]; + + /* Check for uncalibrated devices */ + if (values[CPM1_CALIBSCALE] =3D=3D CM32181_CALIBSCALE_DEFAULT) + goto cpm_parsing_done; + + cm32181->calibscale =3D values[CPM1_CALIBSCALE]; + /* CPM1 lux_per_bit is for the current it value */ + cm32181_read_als_it(cm32181, &cm32181->lux_per_bit_base_it); + } +cpm_parsing_done: +#endif /* CONFIG_ACPI */ + /* Initialize registers*/ for (i =3D 0; i < CM32181_CONF_REG_NUM; i++) { if (cm32181->init_regs_bitmap & BIT(i)) { --=20 2.26.0