From patchwork Mon Jun 6 08:48:52 2016 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Bartosz Golaszewski X-Patchwork-Id: 69370 Delivered-To: patch@linaro.org Received: by 10.140.106.246 with SMTP id e109csp1375367qgf; Mon, 6 Jun 2016 01:49:25 -0700 (PDT) X-Received: by 10.36.25.83 with SMTP id b80mr14123737itb.29.1465202964501; Mon, 06 Jun 2016 01:49:24 -0700 (PDT) Return-Path: Received: from vger.kernel.org (vger.kernel.org. [209.132.180.67]) by mx.google.com with ESMTP id w6si25392752pac.26.2016.06.06.01.49.24; Mon, 06 Jun 2016 01:49:24 -0700 (PDT) Received-SPF: pass (google.com: best guess record for domain of linux-i2c-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) client-ip=209.132.180.67; Authentication-Results: mx.google.com; dkim=neutral (body hash did not verify) header.i=@baylibre-com.20150623.gappssmtp.com; spf=pass (google.com: best guess record for domain of linux-i2c-owner@vger.kernel.org designates 209.132.180.67 as permitted sender) smtp.mailfrom=linux-i2c-owner@vger.kernel.org Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1752463AbcFFItW (ORCPT + 1 other); Mon, 6 Jun 2016 04:49:22 -0400 Received: from mail-wm0-f54.google.com ([74.125.82.54]:37526 "EHLO mail-wm0-f54.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1752303AbcFFItS (ORCPT ); Mon, 6 Jun 2016 04:49:18 -0400 Received: by mail-wm0-f54.google.com with SMTP id k204so16919317wmk.0 for ; Mon, 06 Jun 2016 01:49:17 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=baylibre-com.20150623.gappssmtp.com; s=20150623; h=from:to:cc:subject:date:message-id:in-reply-to:references; bh=nCzAO+k5SurZ54+MhHXiDs/1AJGd8RVIsJl81P3hzKs=; b=EH1MUpHTHBN7Lk2DbMGp7UC2EsbERADhLn2lTOGuOyhAwbEpHyAl0BcfySVZyr6itV LEj1sg7dQ/LHbx1aLHZUaxEtTj9V+JSU6r6AGvswpgzzWwVuUNDS4ok3x1TVXRabE43V NYPY3Mc5udWvGwnnI85BYoTL+3tcBNC/RtYtX4++J632YHVJS95n3tGH52oJNpg+xdNt 3SL/cjmkR5scZUBMuV6Q8nMHOV5topxYvchtxg/8D9vlTz+0ieuGC/beW4KuG/KwK4nE IMz9JTsmA3rIsuT0LNJhS/L0QKZjoopj5x/HgavuZoMrNfqyfK2ibr4geUI51x7hKuJu Q2Hg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20130820; h=x-gm-message-state:from:to:cc:subject:date:message-id:in-reply-to :references; bh=nCzAO+k5SurZ54+MhHXiDs/1AJGd8RVIsJl81P3hzKs=; b=OlcqcHozq4quGRp2nDMSobsai4ojkQBQQ1K2nvtFW51JebPgi9Zw1aM0GqnkwN+qP9 0kh/EsPi8+Thj+qIOR6KsUr6NDjJpveVhEzNDtiHi1jZSEQkF3CS/YHeO0iMOd0bAf07 kk6VQXSkxDb2wrBdeC5sz+bX3wPxwPUn/iLdXHa4CBe1tFgNnkPgWQD4fGXdyBEMkwEN hS+Ihxv+8PlFFji5nn275y2n9ulGFh3wgUwD81D82XY2rzgFWNMP0C9AAoTMXMC19cme 1t/8CTOSWq0+fiEKoAEq4Kr8SnG7oYRWI1G51mIfwONtn65ojifXyopN1Fk8lOlfwCdV L8Cg== X-Gm-Message-State: ALyK8tKkazpnz4+LR7/ofPImLKfWo6mTOPyjmyQPXWWsONIyvAuPsL9TDTGPaPX8CKBknXWt X-Received: by 10.194.103.105 with SMTP id fv9mr14405602wjb.162.1465202956693; Mon, 06 Jun 2016 01:49:16 -0700 (PDT) Received: from localhost.localdomain ([90.63.244.31]) by smtp.gmail.com with ESMTPSA id dd7sm19090384wjb.22.2016.06.06.01.49.15 (version=TLS1_2 cipher=ECDHE-RSA-AES128-SHA bits=128/128); Mon, 06 Jun 2016 01:49:16 -0700 (PDT) From: Bartosz Golaszewski To: Wolfram Sang , linux-i2c , LKML , Andrew Lunn , Srinivas Kandagatla , Maxime Ripard , GregKH Cc: Bartosz Golaszewski Subject: [RESEND PATCH 10/14] eeprom: at24: support reading the serial number Date: Mon, 6 Jun 2016 10:48:52 +0200 Message-Id: <1465202936-16832-11-git-send-email-bgolaszewski@baylibre.com> X-Mailer: git-send-email 2.1.4 In-Reply-To: <1465202936-16832-1-git-send-email-bgolaszewski@baylibre.com> References: <1465202936-16832-1-git-send-email-bgolaszewski@baylibre.com> Sender: linux-i2c-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-i2c@vger.kernel.org The at24cs series EEPROM chips have an additional read-only memory area containing a factory pre-programmed serial number. In order to access it, one has to perform a dummy write before reading the serial number bytes. Add a function that allows to access the serial number and assign it to at24->read_func if the chip allows serial number read operations and the driver was passed the relevant flag for this device. Signed-off-by: Bartosz Golaszewski --- drivers/misc/eeprom/at24.c | 62 ++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 2 deletions(-) -- 2.7.4 -- To unsubscribe from this list: send the line "unsubscribe linux-i2c" in the body of a message to majordomo@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html diff --git a/drivers/misc/eeprom/at24.c b/drivers/misc/eeprom/at24.c index 6acf35a..29bbdad 100644 --- a/drivers/misc/eeprom/at24.c +++ b/drivers/misc/eeprom/at24.c @@ -276,6 +276,59 @@ static ssize_t at24_eeprom_read_i2c(struct at24_data *at24, char *buf, return -ETIMEDOUT; } +static ssize_t at24_eeprom_read_serial(struct at24_data *at24, char *buf, + unsigned int offset, size_t count) +{ + unsigned long timeout, read_time; + struct i2c_client *client; + struct i2c_msg msg[2]; + u8 addrbuf[2]; + int status; + + client = at24_translate_offset(at24, &offset); + + memset(msg, 0, sizeof(msg)); + msg[0].addr = client->addr; + msg[0].buf = addrbuf; + + /* + * The address pointer of the device is shared between the regular + * EEPROM array and the serial number block. The dummy write (part of + * the sequential read protocol) ensures the address pointer is reset + * to the desired position. + */ + if (at24->chip.flags & AT24_FLAG_ADDR16) { + /* + * For 16 bit address pointers, the word address must contain + * a '10' sequence in bits 11 and 10 regardless of the + * intended position of the address pointer. + */ + addrbuf[0] = 0x08; + addrbuf[1] = offset; + msg[0].len = 2; + } else { + /* + * Otherwise the word address must begin with a '10' sequence, + * regardless of the intended address. + */ + addrbuf[0] = 0x80 + offset; + msg[0].len = 1; + } + + msg[1].addr = client->addr; + msg[1].flags = I2C_M_RD; + msg[1].buf = buf; + msg[1].len = count; + + loop_until_timeout(timeout, read_time) { + status = i2c_transfer(client->adapter, msg, 2); + if (status == 2) + return count; + } + + return -ETIMEDOUT; +} + /* * Note that if the hardware write-protect pin is pulled high, the whole * chip is normally write protected. But there are plenty of product @@ -577,8 +630,13 @@ static int at24_probe(struct i2c_client *client, const struct i2c_device_id *id) at24->chip = chip; at24->num_addresses = num_addresses; - at24->read_func = at24->use_smbus ? at24_eeprom_read_smbus - : at24_eeprom_read_i2c; + if (chip.flags & AT24_FLAG_SERIAL) { + at24->read_func = at24_eeprom_read_serial; + } else { + at24->read_func = at24->use_smbus ? at24_eeprom_read_smbus + : at24_eeprom_read_i2c; + } + if (at24->use_smbus) { if (at24->use_smbus_write == I2C_SMBUS_I2C_BLOCK_DATA) at24->write_func = at24_eeprom_write_smbus_block;