162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0-or-later
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci *	ds2490.c  USB to one wire bridge
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright (c) 2004 Evgeniy Polyakov <zbr@ioremap.net>
662306a36Sopenharmony_ci */
762306a36Sopenharmony_ci
862306a36Sopenharmony_ci#include <linux/module.h>
962306a36Sopenharmony_ci#include <linux/kernel.h>
1062306a36Sopenharmony_ci#include <linux/mod_devicetable.h>
1162306a36Sopenharmony_ci#include <linux/usb.h>
1262306a36Sopenharmony_ci#include <linux/slab.h>
1362306a36Sopenharmony_ci
1462306a36Sopenharmony_ci#include <linux/w1.h>
1562306a36Sopenharmony_ci
1662306a36Sopenharmony_ci/* USB Standard */
1762306a36Sopenharmony_ci/* USB Control request vendor type */
1862306a36Sopenharmony_ci#define VENDOR				0x40
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_ci/* COMMAND TYPE CODES */
2162306a36Sopenharmony_ci#define CONTROL_CMD			0x00
2262306a36Sopenharmony_ci#define COMM_CMD			0x01
2362306a36Sopenharmony_ci#define MODE_CMD			0x02
2462306a36Sopenharmony_ci
2562306a36Sopenharmony_ci/* CONTROL COMMAND CODES */
2662306a36Sopenharmony_ci#define CTL_RESET_DEVICE		0x0000
2762306a36Sopenharmony_ci#define CTL_START_EXE			0x0001
2862306a36Sopenharmony_ci#define CTL_RESUME_EXE			0x0002
2962306a36Sopenharmony_ci#define CTL_HALT_EXE_IDLE		0x0003
3062306a36Sopenharmony_ci#define CTL_HALT_EXE_DONE		0x0004
3162306a36Sopenharmony_ci#define CTL_FLUSH_COMM_CMDS		0x0007
3262306a36Sopenharmony_ci#define CTL_FLUSH_RCV_BUFFER		0x0008
3362306a36Sopenharmony_ci#define CTL_FLUSH_XMT_BUFFER		0x0009
3462306a36Sopenharmony_ci#define CTL_GET_COMM_CMDS		0x000A
3562306a36Sopenharmony_ci
3662306a36Sopenharmony_ci/* MODE COMMAND CODES */
3762306a36Sopenharmony_ci#define MOD_PULSE_EN			0x0000
3862306a36Sopenharmony_ci#define MOD_SPEED_CHANGE_EN		0x0001
3962306a36Sopenharmony_ci#define MOD_1WIRE_SPEED			0x0002
4062306a36Sopenharmony_ci#define MOD_STRONG_PU_DURATION		0x0003
4162306a36Sopenharmony_ci#define MOD_PULLDOWN_SLEWRATE		0x0004
4262306a36Sopenharmony_ci#define MOD_PROG_PULSE_DURATION		0x0005
4362306a36Sopenharmony_ci#define MOD_WRITE1_LOWTIME		0x0006
4462306a36Sopenharmony_ci#define MOD_DSOW0_TREC			0x0007
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_ci/* COMMUNICATION COMMAND CODES */
4762306a36Sopenharmony_ci#define COMM_ERROR_ESCAPE		0x0601
4862306a36Sopenharmony_ci#define COMM_SET_DURATION		0x0012
4962306a36Sopenharmony_ci#define COMM_BIT_IO			0x0020
5062306a36Sopenharmony_ci#define COMM_PULSE			0x0030
5162306a36Sopenharmony_ci#define COMM_1_WIRE_RESET		0x0042
5262306a36Sopenharmony_ci#define COMM_BYTE_IO			0x0052
5362306a36Sopenharmony_ci#define COMM_MATCH_ACCESS		0x0064
5462306a36Sopenharmony_ci#define COMM_BLOCK_IO			0x0074
5562306a36Sopenharmony_ci#define COMM_READ_STRAIGHT		0x0080
5662306a36Sopenharmony_ci#define COMM_DO_RELEASE			0x6092
5762306a36Sopenharmony_ci#define COMM_SET_PATH			0x00A2
5862306a36Sopenharmony_ci#define COMM_WRITE_SRAM_PAGE		0x00B2
5962306a36Sopenharmony_ci#define COMM_WRITE_EPROM		0x00C4
6062306a36Sopenharmony_ci#define COMM_READ_CRC_PROT_PAGE		0x00D4
6162306a36Sopenharmony_ci#define COMM_READ_REDIRECT_PAGE_CRC	0x21E4
6262306a36Sopenharmony_ci#define COMM_SEARCH_ACCESS		0x00F4
6362306a36Sopenharmony_ci
6462306a36Sopenharmony_ci/* Communication command bits */
6562306a36Sopenharmony_ci#define COMM_TYPE			0x0008
6662306a36Sopenharmony_ci#define COMM_SE				0x0008
6762306a36Sopenharmony_ci#define COMM_D				0x0008
6862306a36Sopenharmony_ci#define COMM_Z				0x0008
6962306a36Sopenharmony_ci#define COMM_CH				0x0008
7062306a36Sopenharmony_ci#define COMM_SM				0x0008
7162306a36Sopenharmony_ci#define COMM_R				0x0008
7262306a36Sopenharmony_ci#define COMM_IM				0x0001
7362306a36Sopenharmony_ci
7462306a36Sopenharmony_ci#define COMM_PS				0x4000
7562306a36Sopenharmony_ci#define COMM_PST			0x4000
7662306a36Sopenharmony_ci#define COMM_CIB			0x4000
7762306a36Sopenharmony_ci#define COMM_RTS			0x4000
7862306a36Sopenharmony_ci#define COMM_DT				0x2000
7962306a36Sopenharmony_ci#define COMM_SPU			0x1000
8062306a36Sopenharmony_ci#define COMM_F				0x0800
8162306a36Sopenharmony_ci#define COMM_NTF			0x0400
8262306a36Sopenharmony_ci#define COMM_ICP			0x0200
8362306a36Sopenharmony_ci#define COMM_RST			0x0100
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_ci#define PULSE_PROG			0x01
8662306a36Sopenharmony_ci#define PULSE_SPUE			0x02
8762306a36Sopenharmony_ci
8862306a36Sopenharmony_ci#define BRANCH_MAIN			0xCC
8962306a36Sopenharmony_ci#define BRANCH_AUX			0x33
9062306a36Sopenharmony_ci
9162306a36Sopenharmony_ci/* Status flags */
9262306a36Sopenharmony_ci#define ST_SPUA				0x01  /* Strong Pull-up is active */
9362306a36Sopenharmony_ci#define ST_PRGA				0x02  /* 12V programming pulse is being generated */
9462306a36Sopenharmony_ci#define ST_12VP				0x04  /* external 12V programming voltage is present */
9562306a36Sopenharmony_ci#define ST_PMOD				0x08  /* DS2490 powered from USB and external sources */
9662306a36Sopenharmony_ci#define ST_HALT				0x10  /* DS2490 is currently halted */
9762306a36Sopenharmony_ci#define ST_IDLE				0x20  /* DS2490 is currently idle */
9862306a36Sopenharmony_ci#define ST_EPOF				0x80
9962306a36Sopenharmony_ci/* Status transfer size, 16 bytes status, 16 byte result flags */
10062306a36Sopenharmony_ci#define ST_SIZE				0x20
10162306a36Sopenharmony_ci
10262306a36Sopenharmony_ci/* Result Register flags */
10362306a36Sopenharmony_ci#define RR_DETECT			0xA5 /* New device detected */
10462306a36Sopenharmony_ci#define RR_NRS				0x01 /* Reset no presence or ... */
10562306a36Sopenharmony_ci#define RR_SH				0x02 /* short on reset or set path */
10662306a36Sopenharmony_ci#define RR_APP				0x04 /* alarming presence on reset */
10762306a36Sopenharmony_ci#define RR_VPP				0x08 /* 12V expected not seen */
10862306a36Sopenharmony_ci#define RR_CMP				0x10 /* compare error */
10962306a36Sopenharmony_ci#define RR_CRC				0x20 /* CRC error detected */
11062306a36Sopenharmony_ci#define RR_RDP				0x40 /* redirected page */
11162306a36Sopenharmony_ci#define RR_EOS				0x80 /* end of search error */
11262306a36Sopenharmony_ci
11362306a36Sopenharmony_ci#define SPEED_NORMAL			0x00
11462306a36Sopenharmony_ci#define SPEED_FLEXIBLE			0x01
11562306a36Sopenharmony_ci#define SPEED_OVERDRIVE			0x02
11662306a36Sopenharmony_ci
11762306a36Sopenharmony_ci#define NUM_EP				4
11862306a36Sopenharmony_ci#define EP_CONTROL			0
11962306a36Sopenharmony_ci#define EP_STATUS			1
12062306a36Sopenharmony_ci#define EP_DATA_OUT			2
12162306a36Sopenharmony_ci#define EP_DATA_IN			3
12262306a36Sopenharmony_ci
12362306a36Sopenharmony_cistruct ds_device {
12462306a36Sopenharmony_ci	struct list_head	ds_entry;
12562306a36Sopenharmony_ci
12662306a36Sopenharmony_ci	struct usb_device	*udev;
12762306a36Sopenharmony_ci	struct usb_interface	*intf;
12862306a36Sopenharmony_ci
12962306a36Sopenharmony_ci	int			ep[NUM_EP];
13062306a36Sopenharmony_ci
13162306a36Sopenharmony_ci	/* Strong PullUp
13262306a36Sopenharmony_ci	 * 0: pullup not active, else duration in milliseconds
13362306a36Sopenharmony_ci	 */
13462306a36Sopenharmony_ci	int			spu_sleep;
13562306a36Sopenharmony_ci	/* spu_bit contains COMM_SPU or 0 depending on if the strong pullup
13662306a36Sopenharmony_ci	 * should be active or not for writes.
13762306a36Sopenharmony_ci	 */
13862306a36Sopenharmony_ci	u16			spu_bit;
13962306a36Sopenharmony_ci
14062306a36Sopenharmony_ci	u8			st_buf[ST_SIZE];
14162306a36Sopenharmony_ci	u8			byte_buf;
14262306a36Sopenharmony_ci
14362306a36Sopenharmony_ci	struct w1_bus_master	master;
14462306a36Sopenharmony_ci};
14562306a36Sopenharmony_ci
14662306a36Sopenharmony_cistruct ds_status {
14762306a36Sopenharmony_ci	u8			enable;
14862306a36Sopenharmony_ci	u8			speed;
14962306a36Sopenharmony_ci	u8			pullup_dur;
15062306a36Sopenharmony_ci	u8			ppuls_dur;
15162306a36Sopenharmony_ci	u8			pulldown_slew;
15262306a36Sopenharmony_ci	u8			write1_time;
15362306a36Sopenharmony_ci	u8			write0_time;
15462306a36Sopenharmony_ci	u8			reserved0;
15562306a36Sopenharmony_ci	u8			status;
15662306a36Sopenharmony_ci	u8			command0;
15762306a36Sopenharmony_ci	u8			command1;
15862306a36Sopenharmony_ci	u8			command_buffer_status;
15962306a36Sopenharmony_ci	u8			data_out_buffer_status;
16062306a36Sopenharmony_ci	u8			data_in_buffer_status;
16162306a36Sopenharmony_ci	u8			reserved1;
16262306a36Sopenharmony_ci	u8			reserved2;
16362306a36Sopenharmony_ci};
16462306a36Sopenharmony_ci
16562306a36Sopenharmony_cistatic LIST_HEAD(ds_devices);
16662306a36Sopenharmony_cistatic DEFINE_MUTEX(ds_mutex);
16762306a36Sopenharmony_ci
16862306a36Sopenharmony_cistatic int ds_send_control_cmd(struct ds_device *dev, u16 value, u16 index)
16962306a36Sopenharmony_ci{
17062306a36Sopenharmony_ci	int err;
17162306a36Sopenharmony_ci
17262306a36Sopenharmony_ci	err = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, dev->ep[EP_CONTROL]),
17362306a36Sopenharmony_ci			CONTROL_CMD, VENDOR, value, index, NULL, 0, 1000);
17462306a36Sopenharmony_ci	if (err < 0) {
17562306a36Sopenharmony_ci		dev_err(&dev->udev->dev,
17662306a36Sopenharmony_ci			"Failed to send command control message %x.%x: err=%d.\n",
17762306a36Sopenharmony_ci			value, index, err);
17862306a36Sopenharmony_ci		return err;
17962306a36Sopenharmony_ci	}
18062306a36Sopenharmony_ci
18162306a36Sopenharmony_ci	return err;
18262306a36Sopenharmony_ci}
18362306a36Sopenharmony_ci
18462306a36Sopenharmony_cistatic int ds_send_control_mode(struct ds_device *dev, u16 value, u16 index)
18562306a36Sopenharmony_ci{
18662306a36Sopenharmony_ci	int err;
18762306a36Sopenharmony_ci
18862306a36Sopenharmony_ci	err = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, dev->ep[EP_CONTROL]),
18962306a36Sopenharmony_ci			MODE_CMD, VENDOR, value, index, NULL, 0, 1000);
19062306a36Sopenharmony_ci	if (err < 0) {
19162306a36Sopenharmony_ci		dev_err(&dev->udev->dev,
19262306a36Sopenharmony_ci			"Failed to send mode control message %x.%x: err=%d.\n",
19362306a36Sopenharmony_ci			value, index, err);
19462306a36Sopenharmony_ci		return err;
19562306a36Sopenharmony_ci	}
19662306a36Sopenharmony_ci
19762306a36Sopenharmony_ci	return err;
19862306a36Sopenharmony_ci}
19962306a36Sopenharmony_ci
20062306a36Sopenharmony_cistatic int ds_send_control(struct ds_device *dev, u16 value, u16 index)
20162306a36Sopenharmony_ci{
20262306a36Sopenharmony_ci	int err;
20362306a36Sopenharmony_ci
20462306a36Sopenharmony_ci	err = usb_control_msg(dev->udev, usb_sndctrlpipe(dev->udev, dev->ep[EP_CONTROL]),
20562306a36Sopenharmony_ci			COMM_CMD, VENDOR, value, index, NULL, 0, 1000);
20662306a36Sopenharmony_ci	if (err < 0) {
20762306a36Sopenharmony_ci		dev_err(&dev->udev->dev,
20862306a36Sopenharmony_ci			"Failed to send control message %x.%x: err=%d.\n",
20962306a36Sopenharmony_ci			value, index, err);
21062306a36Sopenharmony_ci		return err;
21162306a36Sopenharmony_ci	}
21262306a36Sopenharmony_ci
21362306a36Sopenharmony_ci	return err;
21462306a36Sopenharmony_ci}
21562306a36Sopenharmony_ci
21662306a36Sopenharmony_cistatic void ds_dump_status(struct ds_device *ds_dev, unsigned char *buf, int count)
21762306a36Sopenharmony_ci{
21862306a36Sopenharmony_ci	struct device *dev = &ds_dev->udev->dev;
21962306a36Sopenharmony_ci	int i;
22062306a36Sopenharmony_ci
22162306a36Sopenharmony_ci	dev_info(dev, "ep_status=0x%x, count=%d, status=%*phC",
22262306a36Sopenharmony_ci		ds_dev->ep[EP_STATUS], count, count, buf);
22362306a36Sopenharmony_ci
22462306a36Sopenharmony_ci	if (count >= 16) {
22562306a36Sopenharmony_ci		dev_dbg(dev, "enable flag: 0x%02x", buf[0]);
22662306a36Sopenharmony_ci		dev_dbg(dev, "1-wire speed: 0x%02x", buf[1]);
22762306a36Sopenharmony_ci		dev_dbg(dev, "strong pullup duration: 0x%02x", buf[2]);
22862306a36Sopenharmony_ci		dev_dbg(dev, "programming pulse duration: 0x%02x", buf[3]);
22962306a36Sopenharmony_ci		dev_dbg(dev, "pulldown slew rate control: 0x%02x", buf[4]);
23062306a36Sopenharmony_ci		dev_dbg(dev, "write-1 low time: 0x%02x", buf[5]);
23162306a36Sopenharmony_ci		dev_dbg(dev, "data sample offset/write-0 recovery time: 0x%02x", buf[6]);
23262306a36Sopenharmony_ci		dev_dbg(dev, "reserved (test register): 0x%02x", buf[7]);
23362306a36Sopenharmony_ci		dev_dbg(dev, "device status flags: 0x%02x", buf[8]);
23462306a36Sopenharmony_ci		dev_dbg(dev, "communication command byte 1: 0x%02x", buf[9]);
23562306a36Sopenharmony_ci		dev_dbg(dev, "communication command byte 2: 0x%02x", buf[10]);
23662306a36Sopenharmony_ci		dev_dbg(dev, "communication command buffer status: 0x%02x", buf[11]);
23762306a36Sopenharmony_ci		dev_dbg(dev, "1-wire data output buffer status: 0x%02x", buf[12]);
23862306a36Sopenharmony_ci		dev_dbg(dev, "1-wire data input buffer status: 0x%02x", buf[13]);
23962306a36Sopenharmony_ci		dev_dbg(dev, "reserved: 0x%02x", buf[14]);
24062306a36Sopenharmony_ci		dev_dbg(dev, "reserved: 0x%02x", buf[15]);
24162306a36Sopenharmony_ci	}
24262306a36Sopenharmony_ci
24362306a36Sopenharmony_ci	for (i = 16; i < count; ++i) {
24462306a36Sopenharmony_ci		if (buf[i] == RR_DETECT) {
24562306a36Sopenharmony_ci			dev_dbg(dev, "New device detect.\n");
24662306a36Sopenharmony_ci			continue;
24762306a36Sopenharmony_ci		}
24862306a36Sopenharmony_ci		dev_dbg(dev, "Result Register Value: 0x%02x", buf[i]);
24962306a36Sopenharmony_ci		if (buf[i] & RR_NRS)
25062306a36Sopenharmony_ci			dev_dbg(dev, "NRS: Reset no presence or ...\n");
25162306a36Sopenharmony_ci		if (buf[i] & RR_SH)
25262306a36Sopenharmony_ci			dev_dbg(dev, "SH: short on reset or set path\n");
25362306a36Sopenharmony_ci		if (buf[i] & RR_APP)
25462306a36Sopenharmony_ci			dev_dbg(dev, "APP: alarming presence on reset\n");
25562306a36Sopenharmony_ci		if (buf[i] & RR_VPP)
25662306a36Sopenharmony_ci			dev_dbg(dev, "VPP: 12V expected not seen\n");
25762306a36Sopenharmony_ci		if (buf[i] & RR_CMP)
25862306a36Sopenharmony_ci			dev_dbg(dev, "CMP: compare error\n");
25962306a36Sopenharmony_ci		if (buf[i] & RR_CRC)
26062306a36Sopenharmony_ci			dev_dbg(dev, "CRC: CRC error detected\n");
26162306a36Sopenharmony_ci		if (buf[i] & RR_RDP)
26262306a36Sopenharmony_ci			dev_dbg(dev, "RDP: redirected page\n");
26362306a36Sopenharmony_ci		if (buf[i] & RR_EOS)
26462306a36Sopenharmony_ci			dev_dbg(dev, "EOS: end of search error\n");
26562306a36Sopenharmony_ci	}
26662306a36Sopenharmony_ci}
26762306a36Sopenharmony_ci
26862306a36Sopenharmony_cistatic int ds_recv_status(struct ds_device *dev, struct ds_status *st)
26962306a36Sopenharmony_ci{
27062306a36Sopenharmony_ci	int count, err;
27162306a36Sopenharmony_ci
27262306a36Sopenharmony_ci	if (st)
27362306a36Sopenharmony_ci		memset(st, 0, sizeof(*st));
27462306a36Sopenharmony_ci
27562306a36Sopenharmony_ci	count = 0;
27662306a36Sopenharmony_ci	err = usb_interrupt_msg(dev->udev,
27762306a36Sopenharmony_ci				usb_rcvintpipe(dev->udev,
27862306a36Sopenharmony_ci					       dev->ep[EP_STATUS]),
27962306a36Sopenharmony_ci				dev->st_buf, sizeof(dev->st_buf),
28062306a36Sopenharmony_ci				&count, 1000);
28162306a36Sopenharmony_ci	if (err < 0) {
28262306a36Sopenharmony_ci		dev_err(&dev->udev->dev,
28362306a36Sopenharmony_ci			"Failed to read 1-wire data from 0x%x: err=%d.\n",
28462306a36Sopenharmony_ci			dev->ep[EP_STATUS], err);
28562306a36Sopenharmony_ci		return err;
28662306a36Sopenharmony_ci	}
28762306a36Sopenharmony_ci
28862306a36Sopenharmony_ci	if (st && count >= sizeof(*st))
28962306a36Sopenharmony_ci		memcpy(st, dev->st_buf, sizeof(*st));
29062306a36Sopenharmony_ci
29162306a36Sopenharmony_ci	return count;
29262306a36Sopenharmony_ci}
29362306a36Sopenharmony_ci
29462306a36Sopenharmony_cistatic void ds_reset_device(struct ds_device *dev)
29562306a36Sopenharmony_ci{
29662306a36Sopenharmony_ci	ds_send_control_cmd(dev, CTL_RESET_DEVICE, 0);
29762306a36Sopenharmony_ci	/* Always allow strong pullup which allow individual writes to use
29862306a36Sopenharmony_ci	 * the strong pullup.
29962306a36Sopenharmony_ci	 */
30062306a36Sopenharmony_ci	if (ds_send_control_mode(dev, MOD_PULSE_EN, PULSE_SPUE))
30162306a36Sopenharmony_ci		dev_err(&dev->udev->dev,
30262306a36Sopenharmony_ci			"%s: Error allowing strong pullup\n", __func__);
30362306a36Sopenharmony_ci	/* Chip strong pullup time was cleared. */
30462306a36Sopenharmony_ci	if (dev->spu_sleep) {
30562306a36Sopenharmony_ci		/* lower 4 bits are 0, see ds_set_pullup */
30662306a36Sopenharmony_ci		u8 del = dev->spu_sleep>>4;
30762306a36Sopenharmony_ci
30862306a36Sopenharmony_ci		if (ds_send_control(dev, COMM_SET_DURATION | COMM_IM, del))
30962306a36Sopenharmony_ci			dev_err(&dev->udev->dev,
31062306a36Sopenharmony_ci				"%s: Error setting duration\n", __func__);
31162306a36Sopenharmony_ci	}
31262306a36Sopenharmony_ci}
31362306a36Sopenharmony_ci
31462306a36Sopenharmony_cistatic int ds_recv_data(struct ds_device *dev, unsigned char *buf, int size)
31562306a36Sopenharmony_ci{
31662306a36Sopenharmony_ci	int count, err;
31762306a36Sopenharmony_ci
31862306a36Sopenharmony_ci	/* Careful on size.  If size is less than what is available in
31962306a36Sopenharmony_ci	 * the input buffer, the device fails the bulk transfer and
32062306a36Sopenharmony_ci	 * clears the input buffer.  It could read the maximum size of
32162306a36Sopenharmony_ci	 * the data buffer, but then do you return the first, last, or
32262306a36Sopenharmony_ci	 * some set of the middle size bytes?  As long as the rest of
32362306a36Sopenharmony_ci	 * the code is correct there will be size bytes waiting.  A
32462306a36Sopenharmony_ci	 * call to ds_wait_status will wait until the device is idle
32562306a36Sopenharmony_ci	 * and any data to be received would have been available.
32662306a36Sopenharmony_ci	 */
32762306a36Sopenharmony_ci	count = 0;
32862306a36Sopenharmony_ci	err = usb_bulk_msg(dev->udev, usb_rcvbulkpipe(dev->udev, dev->ep[EP_DATA_IN]),
32962306a36Sopenharmony_ci				buf, size, &count, 1000);
33062306a36Sopenharmony_ci	if (err < 0) {
33162306a36Sopenharmony_ci		int recv_len;
33262306a36Sopenharmony_ci
33362306a36Sopenharmony_ci		dev_info(&dev->udev->dev, "Clearing ep0x%x.\n", dev->ep[EP_DATA_IN]);
33462306a36Sopenharmony_ci		usb_clear_halt(dev->udev, usb_rcvbulkpipe(dev->udev, dev->ep[EP_DATA_IN]));
33562306a36Sopenharmony_ci
33662306a36Sopenharmony_ci		/* status might tell us why endpoint is stuck? */
33762306a36Sopenharmony_ci		recv_len = ds_recv_status(dev, NULL);
33862306a36Sopenharmony_ci		if (recv_len >= 0)
33962306a36Sopenharmony_ci			ds_dump_status(dev, dev->st_buf, recv_len);
34062306a36Sopenharmony_ci
34162306a36Sopenharmony_ci		return err;
34262306a36Sopenharmony_ci	}
34362306a36Sopenharmony_ci
34462306a36Sopenharmony_ci#if 0
34562306a36Sopenharmony_ci	{
34662306a36Sopenharmony_ci		int i;
34762306a36Sopenharmony_ci
34862306a36Sopenharmony_ci		printk("%s: count=%d: ", __func__, count);
34962306a36Sopenharmony_ci		for (i = 0; i < count; ++i)
35062306a36Sopenharmony_ci			printk("%02x ", buf[i]);
35162306a36Sopenharmony_ci		printk("\n");
35262306a36Sopenharmony_ci	}
35362306a36Sopenharmony_ci#endif
35462306a36Sopenharmony_ci	return count;
35562306a36Sopenharmony_ci}
35662306a36Sopenharmony_ci
35762306a36Sopenharmony_cistatic int ds_send_data(struct ds_device *dev, unsigned char *buf, int len)
35862306a36Sopenharmony_ci{
35962306a36Sopenharmony_ci	int count, err;
36062306a36Sopenharmony_ci
36162306a36Sopenharmony_ci	count = 0;
36262306a36Sopenharmony_ci	err = usb_bulk_msg(dev->udev, usb_sndbulkpipe(dev->udev, dev->ep[EP_DATA_OUT]), buf, len, &count, 1000);
36362306a36Sopenharmony_ci	if (err < 0) {
36462306a36Sopenharmony_ci		dev_err(&dev->udev->dev, "Failed to write 1-wire data to ep0x%x: "
36562306a36Sopenharmony_ci			"err=%d.\n", dev->ep[EP_DATA_OUT], err);
36662306a36Sopenharmony_ci		return err;
36762306a36Sopenharmony_ci	}
36862306a36Sopenharmony_ci
36962306a36Sopenharmony_ci	return err;
37062306a36Sopenharmony_ci}
37162306a36Sopenharmony_ci
37262306a36Sopenharmony_ci#if 0
37362306a36Sopenharmony_ci
37462306a36Sopenharmony_ciint ds_stop_pulse(struct ds_device *dev, int limit)
37562306a36Sopenharmony_ci{
37662306a36Sopenharmony_ci	struct ds_status st;
37762306a36Sopenharmony_ci	int count = 0, err = 0;
37862306a36Sopenharmony_ci
37962306a36Sopenharmony_ci	do {
38062306a36Sopenharmony_ci		err = ds_send_control(dev, CTL_HALT_EXE_IDLE, 0);
38162306a36Sopenharmony_ci		if (err)
38262306a36Sopenharmony_ci			break;
38362306a36Sopenharmony_ci		err = ds_send_control(dev, CTL_RESUME_EXE, 0);
38462306a36Sopenharmony_ci		if (err)
38562306a36Sopenharmony_ci			break;
38662306a36Sopenharmony_ci		err = ds_recv_status(dev, &st);
38762306a36Sopenharmony_ci		if (err)
38862306a36Sopenharmony_ci			break;
38962306a36Sopenharmony_ci
39062306a36Sopenharmony_ci		if ((st.status & ST_SPUA) == 0) {
39162306a36Sopenharmony_ci			err = ds_send_control_mode(dev, MOD_PULSE_EN, 0);
39262306a36Sopenharmony_ci			if (err)
39362306a36Sopenharmony_ci				break;
39462306a36Sopenharmony_ci		}
39562306a36Sopenharmony_ci	} while (++count < limit);
39662306a36Sopenharmony_ci
39762306a36Sopenharmony_ci	return err;
39862306a36Sopenharmony_ci}
39962306a36Sopenharmony_ci
40062306a36Sopenharmony_ciint ds_detect(struct ds_device *dev, struct ds_status *st)
40162306a36Sopenharmony_ci{
40262306a36Sopenharmony_ci	int err;
40362306a36Sopenharmony_ci
40462306a36Sopenharmony_ci	err = ds_send_control_cmd(dev, CTL_RESET_DEVICE, 0);
40562306a36Sopenharmony_ci	if (err)
40662306a36Sopenharmony_ci		return err;
40762306a36Sopenharmony_ci
40862306a36Sopenharmony_ci	err = ds_send_control(dev, COMM_SET_DURATION | COMM_IM, 0);
40962306a36Sopenharmony_ci	if (err)
41062306a36Sopenharmony_ci		return err;
41162306a36Sopenharmony_ci
41262306a36Sopenharmony_ci	err = ds_send_control(dev, COMM_SET_DURATION | COMM_IM | COMM_TYPE, 0x40);
41362306a36Sopenharmony_ci	if (err)
41462306a36Sopenharmony_ci		return err;
41562306a36Sopenharmony_ci
41662306a36Sopenharmony_ci	err = ds_send_control_mode(dev, MOD_PULSE_EN, PULSE_PROG);
41762306a36Sopenharmony_ci	if (err)
41862306a36Sopenharmony_ci		return err;
41962306a36Sopenharmony_ci
42062306a36Sopenharmony_ci	err = ds_dump_status(dev, st);
42162306a36Sopenharmony_ci
42262306a36Sopenharmony_ci	return err;
42362306a36Sopenharmony_ci}
42462306a36Sopenharmony_ci
42562306a36Sopenharmony_ci#endif  /*  0  */
42662306a36Sopenharmony_ci
42762306a36Sopenharmony_cistatic int ds_wait_status(struct ds_device *dev, struct ds_status *st)
42862306a36Sopenharmony_ci{
42962306a36Sopenharmony_ci	int err, count = 0;
43062306a36Sopenharmony_ci
43162306a36Sopenharmony_ci	do {
43262306a36Sopenharmony_ci		st->status = 0;
43362306a36Sopenharmony_ci		err = ds_recv_status(dev, st);
43462306a36Sopenharmony_ci#if 0
43562306a36Sopenharmony_ci		if (err >= 0) {
43662306a36Sopenharmony_ci			int i;
43762306a36Sopenharmony_ci			printk("0x%x: count=%d, status: ", dev->ep[EP_STATUS], err);
43862306a36Sopenharmony_ci			for (i = 0; i < err; ++i)
43962306a36Sopenharmony_ci				printk("%02x ", dev->st_buf[i]);
44062306a36Sopenharmony_ci			printk("\n");
44162306a36Sopenharmony_ci		}
44262306a36Sopenharmony_ci#endif
44362306a36Sopenharmony_ci	} while (!(st->status & ST_IDLE) && !(err < 0) && ++count < 100);
44462306a36Sopenharmony_ci
44562306a36Sopenharmony_ci	if (err >= 16 && st->status & ST_EPOF) {
44662306a36Sopenharmony_ci		dev_info(&dev->udev->dev, "Resetting device after ST_EPOF.\n");
44762306a36Sopenharmony_ci		ds_reset_device(dev);
44862306a36Sopenharmony_ci		/* Always dump the device status. */
44962306a36Sopenharmony_ci		count = 101;
45062306a36Sopenharmony_ci	}
45162306a36Sopenharmony_ci
45262306a36Sopenharmony_ci	/* Dump the status for errors or if there is extended return data.
45362306a36Sopenharmony_ci	 * The extended status includes new device detection (maybe someone
45462306a36Sopenharmony_ci	 * can do something with it).
45562306a36Sopenharmony_ci	 */
45662306a36Sopenharmony_ci	if (err > 16 || count >= 100 || err < 0)
45762306a36Sopenharmony_ci		ds_dump_status(dev, dev->st_buf, err);
45862306a36Sopenharmony_ci
45962306a36Sopenharmony_ci	/* Extended data isn't an error.  Well, a short is, but the dump
46062306a36Sopenharmony_ci	 * would have already told the user that and we can't do anything
46162306a36Sopenharmony_ci	 * about it in software anyway.
46262306a36Sopenharmony_ci	 */
46362306a36Sopenharmony_ci	if (count >= 100 || err < 0)
46462306a36Sopenharmony_ci		return -1;
46562306a36Sopenharmony_ci	else
46662306a36Sopenharmony_ci		return 0;
46762306a36Sopenharmony_ci}
46862306a36Sopenharmony_ci
46962306a36Sopenharmony_cistatic int ds_reset(struct ds_device *dev)
47062306a36Sopenharmony_ci{
47162306a36Sopenharmony_ci	int err;
47262306a36Sopenharmony_ci
47362306a36Sopenharmony_ci	/* Other potentionally interesting flags for reset.
47462306a36Sopenharmony_ci	 *
47562306a36Sopenharmony_ci	 * COMM_NTF: Return result register feedback.  This could be used to
47662306a36Sopenharmony_ci	 * detect some conditions such as short, alarming presence, or
47762306a36Sopenharmony_ci	 * detect if a new device was detected.
47862306a36Sopenharmony_ci	 *
47962306a36Sopenharmony_ci	 * COMM_SE which allows SPEED_NORMAL, SPEED_FLEXIBLE, SPEED_OVERDRIVE:
48062306a36Sopenharmony_ci	 * Select the data transfer rate.
48162306a36Sopenharmony_ci	 */
48262306a36Sopenharmony_ci	err = ds_send_control(dev, COMM_1_WIRE_RESET | COMM_IM, SPEED_NORMAL);
48362306a36Sopenharmony_ci	if (err)
48462306a36Sopenharmony_ci		return err;
48562306a36Sopenharmony_ci
48662306a36Sopenharmony_ci	return 0;
48762306a36Sopenharmony_ci}
48862306a36Sopenharmony_ci
48962306a36Sopenharmony_ci#if 0
49062306a36Sopenharmony_cistatic int ds_set_speed(struct ds_device *dev, int speed)
49162306a36Sopenharmony_ci{
49262306a36Sopenharmony_ci	int err;
49362306a36Sopenharmony_ci
49462306a36Sopenharmony_ci	if (speed != SPEED_NORMAL && speed != SPEED_FLEXIBLE && speed != SPEED_OVERDRIVE)
49562306a36Sopenharmony_ci		return -EINVAL;
49662306a36Sopenharmony_ci
49762306a36Sopenharmony_ci	if (speed != SPEED_OVERDRIVE)
49862306a36Sopenharmony_ci		speed = SPEED_FLEXIBLE;
49962306a36Sopenharmony_ci
50062306a36Sopenharmony_ci	speed &= 0xff;
50162306a36Sopenharmony_ci
50262306a36Sopenharmony_ci	err = ds_send_control_mode(dev, MOD_1WIRE_SPEED, speed);
50362306a36Sopenharmony_ci	if (err)
50462306a36Sopenharmony_ci		return err;
50562306a36Sopenharmony_ci
50662306a36Sopenharmony_ci	return err;
50762306a36Sopenharmony_ci}
50862306a36Sopenharmony_ci#endif  /*  0  */
50962306a36Sopenharmony_ci
51062306a36Sopenharmony_cistatic int ds_set_pullup(struct ds_device *dev, int delay)
51162306a36Sopenharmony_ci{
51262306a36Sopenharmony_ci	int err = 0;
51362306a36Sopenharmony_ci	u8 del = 1 + (u8)(delay >> 4);
51462306a36Sopenharmony_ci	/* Just storing delay would not get the trunication and roundup. */
51562306a36Sopenharmony_ci	int ms = del<<4;
51662306a36Sopenharmony_ci
51762306a36Sopenharmony_ci	/* Enable spu_bit if a delay is set. */
51862306a36Sopenharmony_ci	dev->spu_bit = delay ? COMM_SPU : 0;
51962306a36Sopenharmony_ci	/* If delay is zero, it has already been disabled, if the time is
52062306a36Sopenharmony_ci	 * the same as the hardware was last programmed to, there is also
52162306a36Sopenharmony_ci	 * nothing more to do.  Compare with the recalculated value ms
52262306a36Sopenharmony_ci	 * rather than del or delay which can have a different value.
52362306a36Sopenharmony_ci	 */
52462306a36Sopenharmony_ci	if (delay == 0 || ms == dev->spu_sleep)
52562306a36Sopenharmony_ci		return err;
52662306a36Sopenharmony_ci
52762306a36Sopenharmony_ci	err = ds_send_control(dev, COMM_SET_DURATION | COMM_IM, del);
52862306a36Sopenharmony_ci	if (err)
52962306a36Sopenharmony_ci		return err;
53062306a36Sopenharmony_ci
53162306a36Sopenharmony_ci	dev->spu_sleep = ms;
53262306a36Sopenharmony_ci
53362306a36Sopenharmony_ci	return err;
53462306a36Sopenharmony_ci}
53562306a36Sopenharmony_ci
53662306a36Sopenharmony_cistatic int ds_touch_bit(struct ds_device *dev, u8 bit, u8 *tbit)
53762306a36Sopenharmony_ci{
53862306a36Sopenharmony_ci	int err;
53962306a36Sopenharmony_ci	struct ds_status st;
54062306a36Sopenharmony_ci
54162306a36Sopenharmony_ci	err = ds_send_control(dev, COMM_BIT_IO | COMM_IM | (bit ? COMM_D : 0),
54262306a36Sopenharmony_ci		0);
54362306a36Sopenharmony_ci	if (err)
54462306a36Sopenharmony_ci		return err;
54562306a36Sopenharmony_ci
54662306a36Sopenharmony_ci	ds_wait_status(dev, &st);
54762306a36Sopenharmony_ci
54862306a36Sopenharmony_ci	err = ds_recv_data(dev, tbit, sizeof(*tbit));
54962306a36Sopenharmony_ci	if (err < 0)
55062306a36Sopenharmony_ci		return err;
55162306a36Sopenharmony_ci
55262306a36Sopenharmony_ci	return 0;
55362306a36Sopenharmony_ci}
55462306a36Sopenharmony_ci
55562306a36Sopenharmony_ci#if 0
55662306a36Sopenharmony_cistatic int ds_write_bit(struct ds_device *dev, u8 bit)
55762306a36Sopenharmony_ci{
55862306a36Sopenharmony_ci	int err;
55962306a36Sopenharmony_ci	struct ds_status st;
56062306a36Sopenharmony_ci
56162306a36Sopenharmony_ci	/* Set COMM_ICP to write without a readback.  Note, this will
56262306a36Sopenharmony_ci	 * produce one time slot, a down followed by an up with COMM_D
56362306a36Sopenharmony_ci	 * only determing the timing.
56462306a36Sopenharmony_ci	 */
56562306a36Sopenharmony_ci	err = ds_send_control(dev, COMM_BIT_IO | COMM_IM | COMM_ICP |
56662306a36Sopenharmony_ci		(bit ? COMM_D : 0), 0);
56762306a36Sopenharmony_ci	if (err)
56862306a36Sopenharmony_ci		return err;
56962306a36Sopenharmony_ci
57062306a36Sopenharmony_ci	ds_wait_status(dev, &st);
57162306a36Sopenharmony_ci
57262306a36Sopenharmony_ci	return 0;
57362306a36Sopenharmony_ci}
57462306a36Sopenharmony_ci#endif
57562306a36Sopenharmony_ci
57662306a36Sopenharmony_cistatic int ds_write_byte(struct ds_device *dev, u8 byte)
57762306a36Sopenharmony_ci{
57862306a36Sopenharmony_ci	int err;
57962306a36Sopenharmony_ci	struct ds_status st;
58062306a36Sopenharmony_ci
58162306a36Sopenharmony_ci	err = ds_send_control(dev, COMM_BYTE_IO | COMM_IM | dev->spu_bit, byte);
58262306a36Sopenharmony_ci	if (err)
58362306a36Sopenharmony_ci		return err;
58462306a36Sopenharmony_ci
58562306a36Sopenharmony_ci	if (dev->spu_bit)
58662306a36Sopenharmony_ci		msleep(dev->spu_sleep);
58762306a36Sopenharmony_ci
58862306a36Sopenharmony_ci	err = ds_wait_status(dev, &st);
58962306a36Sopenharmony_ci	if (err)
59062306a36Sopenharmony_ci		return err;
59162306a36Sopenharmony_ci
59262306a36Sopenharmony_ci	err = ds_recv_data(dev, &dev->byte_buf, 1);
59362306a36Sopenharmony_ci	if (err < 0)
59462306a36Sopenharmony_ci		return err;
59562306a36Sopenharmony_ci
59662306a36Sopenharmony_ci	return !(byte == dev->byte_buf);
59762306a36Sopenharmony_ci}
59862306a36Sopenharmony_ci
59962306a36Sopenharmony_cistatic int ds_read_byte(struct ds_device *dev, u8 *byte)
60062306a36Sopenharmony_ci{
60162306a36Sopenharmony_ci	int err;
60262306a36Sopenharmony_ci	struct ds_status st;
60362306a36Sopenharmony_ci
60462306a36Sopenharmony_ci	err = ds_send_control(dev, COMM_BYTE_IO | COMM_IM, 0xff);
60562306a36Sopenharmony_ci	if (err)
60662306a36Sopenharmony_ci		return err;
60762306a36Sopenharmony_ci
60862306a36Sopenharmony_ci	ds_wait_status(dev, &st);
60962306a36Sopenharmony_ci
61062306a36Sopenharmony_ci	err = ds_recv_data(dev, byte, sizeof(*byte));
61162306a36Sopenharmony_ci	if (err < 0)
61262306a36Sopenharmony_ci		return err;
61362306a36Sopenharmony_ci
61462306a36Sopenharmony_ci	return 0;
61562306a36Sopenharmony_ci}
61662306a36Sopenharmony_ci
61762306a36Sopenharmony_cistatic int ds_read_block(struct ds_device *dev, u8 *buf, int len)
61862306a36Sopenharmony_ci{
61962306a36Sopenharmony_ci	struct ds_status st;
62062306a36Sopenharmony_ci	int err;
62162306a36Sopenharmony_ci
62262306a36Sopenharmony_ci	if (len > 64*1024)
62362306a36Sopenharmony_ci		return -E2BIG;
62462306a36Sopenharmony_ci
62562306a36Sopenharmony_ci	memset(buf, 0xFF, len);
62662306a36Sopenharmony_ci
62762306a36Sopenharmony_ci	err = ds_send_data(dev, buf, len);
62862306a36Sopenharmony_ci	if (err < 0)
62962306a36Sopenharmony_ci		return err;
63062306a36Sopenharmony_ci
63162306a36Sopenharmony_ci	err = ds_send_control(dev, COMM_BLOCK_IO | COMM_IM, len);
63262306a36Sopenharmony_ci	if (err)
63362306a36Sopenharmony_ci		return err;
63462306a36Sopenharmony_ci
63562306a36Sopenharmony_ci	ds_wait_status(dev, &st);
63662306a36Sopenharmony_ci
63762306a36Sopenharmony_ci	memset(buf, 0x00, len);
63862306a36Sopenharmony_ci	err = ds_recv_data(dev, buf, len);
63962306a36Sopenharmony_ci
64062306a36Sopenharmony_ci	return err;
64162306a36Sopenharmony_ci}
64262306a36Sopenharmony_ci
64362306a36Sopenharmony_cistatic int ds_write_block(struct ds_device *dev, u8 *buf, int len)
64462306a36Sopenharmony_ci{
64562306a36Sopenharmony_ci	int err;
64662306a36Sopenharmony_ci	struct ds_status st;
64762306a36Sopenharmony_ci
64862306a36Sopenharmony_ci	err = ds_send_data(dev, buf, len);
64962306a36Sopenharmony_ci	if (err < 0)
65062306a36Sopenharmony_ci		return err;
65162306a36Sopenharmony_ci
65262306a36Sopenharmony_ci	err = ds_send_control(dev, COMM_BLOCK_IO | COMM_IM | dev->spu_bit, len);
65362306a36Sopenharmony_ci	if (err)
65462306a36Sopenharmony_ci		return err;
65562306a36Sopenharmony_ci
65662306a36Sopenharmony_ci	if (dev->spu_bit)
65762306a36Sopenharmony_ci		msleep(dev->spu_sleep);
65862306a36Sopenharmony_ci
65962306a36Sopenharmony_ci	ds_wait_status(dev, &st);
66062306a36Sopenharmony_ci
66162306a36Sopenharmony_ci	err = ds_recv_data(dev, buf, len);
66262306a36Sopenharmony_ci	if (err < 0)
66362306a36Sopenharmony_ci		return err;
66462306a36Sopenharmony_ci
66562306a36Sopenharmony_ci	return !(err == len);
66662306a36Sopenharmony_ci}
66762306a36Sopenharmony_ci
66862306a36Sopenharmony_cistatic void ds9490r_search(void *data, struct w1_master *master,
66962306a36Sopenharmony_ci	u8 search_type, w1_slave_found_callback callback)
67062306a36Sopenharmony_ci{
67162306a36Sopenharmony_ci	/* When starting with an existing id, the first id returned will
67262306a36Sopenharmony_ci	 * be that device (if it is still on the bus most likely).
67362306a36Sopenharmony_ci	 *
67462306a36Sopenharmony_ci	 * If the number of devices found is less than or equal to the
67562306a36Sopenharmony_ci	 * search_limit, that number of IDs will be returned.  If there are
67662306a36Sopenharmony_ci	 * more, search_limit IDs will be returned followed by a non-zero
67762306a36Sopenharmony_ci	 * discrepency value.
67862306a36Sopenharmony_ci	 */
67962306a36Sopenharmony_ci	struct ds_device *dev = data;
68062306a36Sopenharmony_ci	int err;
68162306a36Sopenharmony_ci	u16 value, index;
68262306a36Sopenharmony_ci	struct ds_status st;
68362306a36Sopenharmony_ci	int search_limit;
68462306a36Sopenharmony_ci	int found = 0;
68562306a36Sopenharmony_ci	int i;
68662306a36Sopenharmony_ci
68762306a36Sopenharmony_ci	/* DS18b20 spec, 13.16 ms per device, 75 per second, sleep for
68862306a36Sopenharmony_ci	 * discovering 8 devices (1 bulk transfer and 1/2 FIFO size) at a time.
68962306a36Sopenharmony_ci	 */
69062306a36Sopenharmony_ci	const unsigned long jtime = msecs_to_jiffies(1000*8/75);
69162306a36Sopenharmony_ci	/* FIFO 128 bytes, bulk packet size 64, read a multiple of the
69262306a36Sopenharmony_ci	 * packet size.
69362306a36Sopenharmony_ci	 */
69462306a36Sopenharmony_ci	const size_t bufsize = 2 * 64;
69562306a36Sopenharmony_ci	u64 *buf, *found_ids;
69662306a36Sopenharmony_ci
69762306a36Sopenharmony_ci	buf = kmalloc(bufsize, GFP_KERNEL);
69862306a36Sopenharmony_ci	if (!buf)
69962306a36Sopenharmony_ci		return;
70062306a36Sopenharmony_ci
70162306a36Sopenharmony_ci	/*
70262306a36Sopenharmony_ci	 * We are holding the bus mutex during the scan, but adding devices via the
70362306a36Sopenharmony_ci	 * callback needs the bus to be unlocked. So we queue up found ids here.
70462306a36Sopenharmony_ci	 */
70562306a36Sopenharmony_ci	found_ids = kmalloc_array(master->max_slave_count, sizeof(u64), GFP_KERNEL);
70662306a36Sopenharmony_ci	if (!found_ids) {
70762306a36Sopenharmony_ci		kfree(buf);
70862306a36Sopenharmony_ci		return;
70962306a36Sopenharmony_ci	}
71062306a36Sopenharmony_ci
71162306a36Sopenharmony_ci	mutex_lock(&master->bus_mutex);
71262306a36Sopenharmony_ci
71362306a36Sopenharmony_ci	/* address to start searching at */
71462306a36Sopenharmony_ci	if (ds_send_data(dev, (u8 *)&master->search_id, 8) < 0)
71562306a36Sopenharmony_ci		goto search_out;
71662306a36Sopenharmony_ci	master->search_id = 0;
71762306a36Sopenharmony_ci
71862306a36Sopenharmony_ci	value = COMM_SEARCH_ACCESS | COMM_IM | COMM_RST | COMM_SM | COMM_F |
71962306a36Sopenharmony_ci		COMM_RTS;
72062306a36Sopenharmony_ci	search_limit = master->max_slave_count;
72162306a36Sopenharmony_ci	if (search_limit > 255)
72262306a36Sopenharmony_ci		search_limit = 0;
72362306a36Sopenharmony_ci	index = search_type | (search_limit << 8);
72462306a36Sopenharmony_ci	if (ds_send_control(dev, value, index) < 0)
72562306a36Sopenharmony_ci		goto search_out;
72662306a36Sopenharmony_ci
72762306a36Sopenharmony_ci	do {
72862306a36Sopenharmony_ci		schedule_timeout(jtime);
72962306a36Sopenharmony_ci
73062306a36Sopenharmony_ci		err = ds_recv_status(dev, &st);
73162306a36Sopenharmony_ci		if (err < 0 || err < sizeof(st))
73262306a36Sopenharmony_ci			break;
73362306a36Sopenharmony_ci
73462306a36Sopenharmony_ci		if (st.data_in_buffer_status) {
73562306a36Sopenharmony_ci			/*
73662306a36Sopenharmony_ci			 * Bulk in can receive partial ids, but when it does
73762306a36Sopenharmony_ci			 * they fail crc and will be discarded anyway.
73862306a36Sopenharmony_ci			 * That has only been seen when status in buffer
73962306a36Sopenharmony_ci			 * is 0 and bulk is read anyway, so don't read
74062306a36Sopenharmony_ci			 * bulk without first checking if status says there
74162306a36Sopenharmony_ci			 * is data to read.
74262306a36Sopenharmony_ci			 */
74362306a36Sopenharmony_ci			err = ds_recv_data(dev, (u8 *)buf, bufsize);
74462306a36Sopenharmony_ci			if (err < 0)
74562306a36Sopenharmony_ci				break;
74662306a36Sopenharmony_ci			for (i = 0; i < err/8; ++i) {
74762306a36Sopenharmony_ci				found_ids[found++] = buf[i];
74862306a36Sopenharmony_ci				/*
74962306a36Sopenharmony_ci				 * can't know if there will be a discrepancy
75062306a36Sopenharmony_ci				 * value after until the next id
75162306a36Sopenharmony_ci				 */
75262306a36Sopenharmony_ci				if (found == search_limit) {
75362306a36Sopenharmony_ci					master->search_id = buf[i];
75462306a36Sopenharmony_ci					break;
75562306a36Sopenharmony_ci				}
75662306a36Sopenharmony_ci			}
75762306a36Sopenharmony_ci		}
75862306a36Sopenharmony_ci
75962306a36Sopenharmony_ci		if (test_bit(W1_ABORT_SEARCH, &master->flags))
76062306a36Sopenharmony_ci			break;
76162306a36Sopenharmony_ci	} while (!(st.status & (ST_IDLE | ST_HALT)));
76262306a36Sopenharmony_ci
76362306a36Sopenharmony_ci	/* only continue the search if some weren't found */
76462306a36Sopenharmony_ci	if (found <= search_limit) {
76562306a36Sopenharmony_ci		master->search_id = 0;
76662306a36Sopenharmony_ci	} else if (!test_bit(W1_WARN_MAX_COUNT, &master->flags)) {
76762306a36Sopenharmony_ci		/*
76862306a36Sopenharmony_ci		 * Only max_slave_count will be scanned in a search,
76962306a36Sopenharmony_ci		 * but it will start where it left off next search
77062306a36Sopenharmony_ci		 * until all ids are identified and then it will start
77162306a36Sopenharmony_ci		 * over.  A continued search will report the previous
77262306a36Sopenharmony_ci		 * last id as the first id (provided it is still on the
77362306a36Sopenharmony_ci		 * bus).
77462306a36Sopenharmony_ci		 */
77562306a36Sopenharmony_ci		dev_info(&dev->udev->dev, "%s: max_slave_count %d reached, "
77662306a36Sopenharmony_ci			"will continue next search.\n", __func__,
77762306a36Sopenharmony_ci			master->max_slave_count);
77862306a36Sopenharmony_ci		set_bit(W1_WARN_MAX_COUNT, &master->flags);
77962306a36Sopenharmony_ci	}
78062306a36Sopenharmony_ci
78162306a36Sopenharmony_cisearch_out:
78262306a36Sopenharmony_ci	mutex_unlock(&master->bus_mutex);
78362306a36Sopenharmony_ci	kfree(buf);
78462306a36Sopenharmony_ci
78562306a36Sopenharmony_ci	for (i = 0; i < found; i++) /* run callback for all queued up IDs */
78662306a36Sopenharmony_ci		callback(master, found_ids[i]);
78762306a36Sopenharmony_ci	kfree(found_ids);
78862306a36Sopenharmony_ci}
78962306a36Sopenharmony_ci
79062306a36Sopenharmony_ci#if 0
79162306a36Sopenharmony_ci/*
79262306a36Sopenharmony_ci * FIXME: if this disabled code is ever used in the future all ds_send_data()
79362306a36Sopenharmony_ci * calls must be changed to use a DMAable buffer.
79462306a36Sopenharmony_ci */
79562306a36Sopenharmony_cistatic int ds_match_access(struct ds_device *dev, u64 init)
79662306a36Sopenharmony_ci{
79762306a36Sopenharmony_ci	int err;
79862306a36Sopenharmony_ci	struct ds_status st;
79962306a36Sopenharmony_ci
80062306a36Sopenharmony_ci	err = ds_send_data(dev, (unsigned char *)&init, sizeof(init));
80162306a36Sopenharmony_ci	if (err)
80262306a36Sopenharmony_ci		return err;
80362306a36Sopenharmony_ci
80462306a36Sopenharmony_ci	ds_wait_status(dev, &st);
80562306a36Sopenharmony_ci
80662306a36Sopenharmony_ci	err = ds_send_control(dev, COMM_MATCH_ACCESS | COMM_IM | COMM_RST, 0x0055);
80762306a36Sopenharmony_ci	if (err)
80862306a36Sopenharmony_ci		return err;
80962306a36Sopenharmony_ci
81062306a36Sopenharmony_ci	ds_wait_status(dev, &st);
81162306a36Sopenharmony_ci
81262306a36Sopenharmony_ci	return 0;
81362306a36Sopenharmony_ci}
81462306a36Sopenharmony_ci
81562306a36Sopenharmony_cistatic int ds_set_path(struct ds_device *dev, u64 init)
81662306a36Sopenharmony_ci{
81762306a36Sopenharmony_ci	int err;
81862306a36Sopenharmony_ci	struct ds_status st;
81962306a36Sopenharmony_ci	u8 buf[9];
82062306a36Sopenharmony_ci
82162306a36Sopenharmony_ci	memcpy(buf, &init, 8);
82262306a36Sopenharmony_ci	buf[8] = BRANCH_MAIN;
82362306a36Sopenharmony_ci
82462306a36Sopenharmony_ci	err = ds_send_data(dev, buf, sizeof(buf));
82562306a36Sopenharmony_ci	if (err)
82662306a36Sopenharmony_ci		return err;
82762306a36Sopenharmony_ci
82862306a36Sopenharmony_ci	ds_wait_status(dev, &st);
82962306a36Sopenharmony_ci
83062306a36Sopenharmony_ci	err = ds_send_control(dev, COMM_SET_PATH | COMM_IM | COMM_RST, 0);
83162306a36Sopenharmony_ci	if (err)
83262306a36Sopenharmony_ci		return err;
83362306a36Sopenharmony_ci
83462306a36Sopenharmony_ci	ds_wait_status(dev, &st);
83562306a36Sopenharmony_ci
83662306a36Sopenharmony_ci	return 0;
83762306a36Sopenharmony_ci}
83862306a36Sopenharmony_ci
83962306a36Sopenharmony_ci#endif  /*  0  */
84062306a36Sopenharmony_ci
84162306a36Sopenharmony_cistatic u8 ds9490r_touch_bit(void *data, u8 bit)
84262306a36Sopenharmony_ci{
84362306a36Sopenharmony_ci	struct ds_device *dev = data;
84462306a36Sopenharmony_ci
84562306a36Sopenharmony_ci	if (ds_touch_bit(dev, bit, &dev->byte_buf))
84662306a36Sopenharmony_ci		return 0;
84762306a36Sopenharmony_ci
84862306a36Sopenharmony_ci	return dev->byte_buf;
84962306a36Sopenharmony_ci}
85062306a36Sopenharmony_ci
85162306a36Sopenharmony_ci#if 0
85262306a36Sopenharmony_cistatic void ds9490r_write_bit(void *data, u8 bit)
85362306a36Sopenharmony_ci{
85462306a36Sopenharmony_ci	struct ds_device *dev = data;
85562306a36Sopenharmony_ci
85662306a36Sopenharmony_ci	ds_write_bit(dev, bit);
85762306a36Sopenharmony_ci}
85862306a36Sopenharmony_ci
85962306a36Sopenharmony_cistatic u8 ds9490r_read_bit(void *data)
86062306a36Sopenharmony_ci{
86162306a36Sopenharmony_ci	struct ds_device *dev = data;
86262306a36Sopenharmony_ci	int err;
86362306a36Sopenharmony_ci
86462306a36Sopenharmony_ci	err = ds_touch_bit(dev, 1, &dev->byte_buf);
86562306a36Sopenharmony_ci	if (err)
86662306a36Sopenharmony_ci		return 0;
86762306a36Sopenharmony_ci
86862306a36Sopenharmony_ci	return dev->byte_buf & 1;
86962306a36Sopenharmony_ci}
87062306a36Sopenharmony_ci#endif
87162306a36Sopenharmony_ci
87262306a36Sopenharmony_cistatic void ds9490r_write_byte(void *data, u8 byte)
87362306a36Sopenharmony_ci{
87462306a36Sopenharmony_ci	struct ds_device *dev = data;
87562306a36Sopenharmony_ci
87662306a36Sopenharmony_ci	ds_write_byte(dev, byte);
87762306a36Sopenharmony_ci}
87862306a36Sopenharmony_ci
87962306a36Sopenharmony_cistatic u8 ds9490r_read_byte(void *data)
88062306a36Sopenharmony_ci{
88162306a36Sopenharmony_ci	struct ds_device *dev = data;
88262306a36Sopenharmony_ci	int err;
88362306a36Sopenharmony_ci
88462306a36Sopenharmony_ci	err = ds_read_byte(dev, &dev->byte_buf);
88562306a36Sopenharmony_ci	if (err)
88662306a36Sopenharmony_ci		return 0;
88762306a36Sopenharmony_ci
88862306a36Sopenharmony_ci	return dev->byte_buf;
88962306a36Sopenharmony_ci}
89062306a36Sopenharmony_ci
89162306a36Sopenharmony_cistatic void ds9490r_write_block(void *data, const u8 *buf, int len)
89262306a36Sopenharmony_ci{
89362306a36Sopenharmony_ci	struct ds_device *dev = data;
89462306a36Sopenharmony_ci	u8 *tbuf;
89562306a36Sopenharmony_ci
89662306a36Sopenharmony_ci	if (len <= 0)
89762306a36Sopenharmony_ci		return;
89862306a36Sopenharmony_ci
89962306a36Sopenharmony_ci	tbuf = kmemdup(buf, len, GFP_KERNEL);
90062306a36Sopenharmony_ci	if (!tbuf)
90162306a36Sopenharmony_ci		return;
90262306a36Sopenharmony_ci
90362306a36Sopenharmony_ci	ds_write_block(dev, tbuf, len);
90462306a36Sopenharmony_ci
90562306a36Sopenharmony_ci	kfree(tbuf);
90662306a36Sopenharmony_ci}
90762306a36Sopenharmony_ci
90862306a36Sopenharmony_cistatic u8 ds9490r_read_block(void *data, u8 *buf, int len)
90962306a36Sopenharmony_ci{
91062306a36Sopenharmony_ci	struct ds_device *dev = data;
91162306a36Sopenharmony_ci	int err;
91262306a36Sopenharmony_ci	u8 *tbuf;
91362306a36Sopenharmony_ci
91462306a36Sopenharmony_ci	if (len <= 0)
91562306a36Sopenharmony_ci		return 0;
91662306a36Sopenharmony_ci
91762306a36Sopenharmony_ci	tbuf = kmalloc(len, GFP_KERNEL);
91862306a36Sopenharmony_ci	if (!tbuf)
91962306a36Sopenharmony_ci		return 0;
92062306a36Sopenharmony_ci
92162306a36Sopenharmony_ci	err = ds_read_block(dev, tbuf, len);
92262306a36Sopenharmony_ci	if (err >= 0)
92362306a36Sopenharmony_ci		memcpy(buf, tbuf, len);
92462306a36Sopenharmony_ci
92562306a36Sopenharmony_ci	kfree(tbuf);
92662306a36Sopenharmony_ci
92762306a36Sopenharmony_ci	return err >= 0 ? len : 0;
92862306a36Sopenharmony_ci}
92962306a36Sopenharmony_ci
93062306a36Sopenharmony_cistatic u8 ds9490r_reset(void *data)
93162306a36Sopenharmony_ci{
93262306a36Sopenharmony_ci	struct ds_device *dev = data;
93362306a36Sopenharmony_ci	int err;
93462306a36Sopenharmony_ci
93562306a36Sopenharmony_ci	err = ds_reset(dev);
93662306a36Sopenharmony_ci	if (err)
93762306a36Sopenharmony_ci		return 1;
93862306a36Sopenharmony_ci
93962306a36Sopenharmony_ci	return 0;
94062306a36Sopenharmony_ci}
94162306a36Sopenharmony_ci
94262306a36Sopenharmony_cistatic u8 ds9490r_set_pullup(void *data, int delay)
94362306a36Sopenharmony_ci{
94462306a36Sopenharmony_ci	struct ds_device *dev = data;
94562306a36Sopenharmony_ci
94662306a36Sopenharmony_ci	if (ds_set_pullup(dev, delay))
94762306a36Sopenharmony_ci		return 1;
94862306a36Sopenharmony_ci
94962306a36Sopenharmony_ci	return 0;
95062306a36Sopenharmony_ci}
95162306a36Sopenharmony_ci
95262306a36Sopenharmony_cistatic int ds_w1_init(struct ds_device *dev)
95362306a36Sopenharmony_ci{
95462306a36Sopenharmony_ci	memset(&dev->master, 0, sizeof(struct w1_bus_master));
95562306a36Sopenharmony_ci
95662306a36Sopenharmony_ci	/* Reset the device as it can be in a bad state.
95762306a36Sopenharmony_ci	 * This is necessary because a block write will wait for data
95862306a36Sopenharmony_ci	 * to be placed in the output buffer and block any later
95962306a36Sopenharmony_ci	 * commands which will keep accumulating and the device will
96062306a36Sopenharmony_ci	 * not be idle.  Another case is removing the ds2490 module
96162306a36Sopenharmony_ci	 * while a bus search is in progress, somehow a few commands
96262306a36Sopenharmony_ci	 * get through, but the input transfers fail leaving data in
96362306a36Sopenharmony_ci	 * the input buffer.  This will cause the next read to fail
96462306a36Sopenharmony_ci	 * see the note in ds_recv_data.
96562306a36Sopenharmony_ci	 */
96662306a36Sopenharmony_ci	ds_reset_device(dev);
96762306a36Sopenharmony_ci
96862306a36Sopenharmony_ci	dev->master.data	= dev;
96962306a36Sopenharmony_ci	dev->master.touch_bit	= &ds9490r_touch_bit;
97062306a36Sopenharmony_ci	/* read_bit and write_bit in w1_bus_master are expected to set and
97162306a36Sopenharmony_ci	 * sample the line level.  For write_bit that means it is expected to
97262306a36Sopenharmony_ci	 * set it to that value and leave it there.  ds2490 only supports an
97362306a36Sopenharmony_ci	 * individual time slot at the lowest level.  The requirement from
97462306a36Sopenharmony_ci	 * pulling the bus state down to reading the state is 15us, something
97562306a36Sopenharmony_ci	 * that isn't realistic on the USB bus anyway.
97662306a36Sopenharmony_ci	dev->master.read_bit	= &ds9490r_read_bit;
97762306a36Sopenharmony_ci	dev->master.write_bit	= &ds9490r_write_bit;
97862306a36Sopenharmony_ci	*/
97962306a36Sopenharmony_ci	dev->master.read_byte	= &ds9490r_read_byte;
98062306a36Sopenharmony_ci	dev->master.write_byte	= &ds9490r_write_byte;
98162306a36Sopenharmony_ci	dev->master.read_block	= &ds9490r_read_block;
98262306a36Sopenharmony_ci	dev->master.write_block	= &ds9490r_write_block;
98362306a36Sopenharmony_ci	dev->master.reset_bus	= &ds9490r_reset;
98462306a36Sopenharmony_ci	dev->master.set_pullup	= &ds9490r_set_pullup;
98562306a36Sopenharmony_ci	dev->master.search	= &ds9490r_search;
98662306a36Sopenharmony_ci
98762306a36Sopenharmony_ci	return w1_add_master_device(&dev->master);
98862306a36Sopenharmony_ci}
98962306a36Sopenharmony_ci
99062306a36Sopenharmony_cistatic void ds_w1_fini(struct ds_device *dev)
99162306a36Sopenharmony_ci{
99262306a36Sopenharmony_ci	w1_remove_master_device(&dev->master);
99362306a36Sopenharmony_ci}
99462306a36Sopenharmony_ci
99562306a36Sopenharmony_cistatic int ds_probe(struct usb_interface *intf,
99662306a36Sopenharmony_ci		    const struct usb_device_id *udev_id)
99762306a36Sopenharmony_ci{
99862306a36Sopenharmony_ci	struct usb_device *udev = interface_to_usbdev(intf);
99962306a36Sopenharmony_ci	struct usb_endpoint_descriptor *endpoint;
100062306a36Sopenharmony_ci	struct usb_host_interface *iface_desc;
100162306a36Sopenharmony_ci	struct ds_device *dev;
100262306a36Sopenharmony_ci	int i, err, alt;
100362306a36Sopenharmony_ci
100462306a36Sopenharmony_ci	dev = kzalloc(sizeof(struct ds_device), GFP_KERNEL);
100562306a36Sopenharmony_ci	if (!dev)
100662306a36Sopenharmony_ci		return -ENOMEM;
100762306a36Sopenharmony_ci
100862306a36Sopenharmony_ci	dev->udev = usb_get_dev(udev);
100962306a36Sopenharmony_ci	if (!dev->udev) {
101062306a36Sopenharmony_ci		err = -ENOMEM;
101162306a36Sopenharmony_ci		goto err_out_free;
101262306a36Sopenharmony_ci	}
101362306a36Sopenharmony_ci	memset(dev->ep, 0, sizeof(dev->ep));
101462306a36Sopenharmony_ci
101562306a36Sopenharmony_ci	usb_set_intfdata(intf, dev);
101662306a36Sopenharmony_ci
101762306a36Sopenharmony_ci	err = usb_reset_configuration(dev->udev);
101862306a36Sopenharmony_ci	if (err) {
101962306a36Sopenharmony_ci		dev_err(&dev->udev->dev,
102062306a36Sopenharmony_ci			"Failed to reset configuration: err=%d.\n", err);
102162306a36Sopenharmony_ci		goto err_out_clear;
102262306a36Sopenharmony_ci	}
102362306a36Sopenharmony_ci
102462306a36Sopenharmony_ci	/* alternative 3, 1ms interrupt (greatly speeds search), 64 byte bulk */
102562306a36Sopenharmony_ci	alt = 3;
102662306a36Sopenharmony_ci	err = usb_set_interface(dev->udev,
102762306a36Sopenharmony_ci		intf->cur_altsetting->desc.bInterfaceNumber, alt);
102862306a36Sopenharmony_ci	if (err) {
102962306a36Sopenharmony_ci		dev_err(&dev->udev->dev, "Failed to set alternative setting %d "
103062306a36Sopenharmony_ci			"for %d interface: err=%d.\n", alt,
103162306a36Sopenharmony_ci			intf->cur_altsetting->desc.bInterfaceNumber, err);
103262306a36Sopenharmony_ci		goto err_out_clear;
103362306a36Sopenharmony_ci	}
103462306a36Sopenharmony_ci
103562306a36Sopenharmony_ci	iface_desc = intf->cur_altsetting;
103662306a36Sopenharmony_ci	if (iface_desc->desc.bNumEndpoints != NUM_EP-1) {
103762306a36Sopenharmony_ci		dev_err(&dev->udev->dev, "Num endpoints=%d. It is not DS9490R.\n",
103862306a36Sopenharmony_ci			iface_desc->desc.bNumEndpoints);
103962306a36Sopenharmony_ci		err = -EINVAL;
104062306a36Sopenharmony_ci		goto err_out_clear;
104162306a36Sopenharmony_ci	}
104262306a36Sopenharmony_ci
104362306a36Sopenharmony_ci	/*
104462306a36Sopenharmony_ci	 * This loop doesn'd show control 0 endpoint,
104562306a36Sopenharmony_ci	 * so we will fill only 1-3 endpoints entry.
104662306a36Sopenharmony_ci	 */
104762306a36Sopenharmony_ci	for (i = 0; i < iface_desc->desc.bNumEndpoints; ++i) {
104862306a36Sopenharmony_ci		endpoint = &iface_desc->endpoint[i].desc;
104962306a36Sopenharmony_ci
105062306a36Sopenharmony_ci		dev->ep[i+1] = endpoint->bEndpointAddress;
105162306a36Sopenharmony_ci#if 0
105262306a36Sopenharmony_ci		printk("%d: addr=%x, size=%d, dir=%s, type=%x\n",
105362306a36Sopenharmony_ci			i, endpoint->bEndpointAddress, le16_to_cpu(endpoint->wMaxPacketSize),
105462306a36Sopenharmony_ci			(endpoint->bEndpointAddress & USB_DIR_IN)?"IN":"OUT",
105562306a36Sopenharmony_ci			endpoint->bmAttributes & USB_ENDPOINT_XFERTYPE_MASK);
105662306a36Sopenharmony_ci#endif
105762306a36Sopenharmony_ci	}
105862306a36Sopenharmony_ci
105962306a36Sopenharmony_ci	err = ds_w1_init(dev);
106062306a36Sopenharmony_ci	if (err)
106162306a36Sopenharmony_ci		goto err_out_clear;
106262306a36Sopenharmony_ci
106362306a36Sopenharmony_ci	mutex_lock(&ds_mutex);
106462306a36Sopenharmony_ci	list_add_tail(&dev->ds_entry, &ds_devices);
106562306a36Sopenharmony_ci	mutex_unlock(&ds_mutex);
106662306a36Sopenharmony_ci
106762306a36Sopenharmony_ci	return 0;
106862306a36Sopenharmony_ci
106962306a36Sopenharmony_cierr_out_clear:
107062306a36Sopenharmony_ci	usb_set_intfdata(intf, NULL);
107162306a36Sopenharmony_ci	usb_put_dev(dev->udev);
107262306a36Sopenharmony_cierr_out_free:
107362306a36Sopenharmony_ci	kfree(dev);
107462306a36Sopenharmony_ci	return err;
107562306a36Sopenharmony_ci}
107662306a36Sopenharmony_ci
107762306a36Sopenharmony_cistatic void ds_disconnect(struct usb_interface *intf)
107862306a36Sopenharmony_ci{
107962306a36Sopenharmony_ci	struct ds_device *dev;
108062306a36Sopenharmony_ci
108162306a36Sopenharmony_ci	dev = usb_get_intfdata(intf);
108262306a36Sopenharmony_ci	if (!dev)
108362306a36Sopenharmony_ci		return;
108462306a36Sopenharmony_ci
108562306a36Sopenharmony_ci	mutex_lock(&ds_mutex);
108662306a36Sopenharmony_ci	list_del(&dev->ds_entry);
108762306a36Sopenharmony_ci	mutex_unlock(&ds_mutex);
108862306a36Sopenharmony_ci
108962306a36Sopenharmony_ci	ds_w1_fini(dev);
109062306a36Sopenharmony_ci
109162306a36Sopenharmony_ci	usb_set_intfdata(intf, NULL);
109262306a36Sopenharmony_ci
109362306a36Sopenharmony_ci	usb_put_dev(dev->udev);
109462306a36Sopenharmony_ci	kfree(dev);
109562306a36Sopenharmony_ci}
109662306a36Sopenharmony_ci
109762306a36Sopenharmony_cistatic const struct usb_device_id ds_id_table[] = {
109862306a36Sopenharmony_ci	{ USB_DEVICE(0x04fa, 0x2490) },
109962306a36Sopenharmony_ci	{ },
110062306a36Sopenharmony_ci};
110162306a36Sopenharmony_ciMODULE_DEVICE_TABLE(usb, ds_id_table);
110262306a36Sopenharmony_ci
110362306a36Sopenharmony_cistatic struct usb_driver ds_driver = {
110462306a36Sopenharmony_ci	.name =		"DS9490R",
110562306a36Sopenharmony_ci	.probe =	ds_probe,
110662306a36Sopenharmony_ci	.disconnect =	ds_disconnect,
110762306a36Sopenharmony_ci	.id_table =	ds_id_table,
110862306a36Sopenharmony_ci};
110962306a36Sopenharmony_cimodule_usb_driver(ds_driver);
111062306a36Sopenharmony_ci
111162306a36Sopenharmony_ciMODULE_AUTHOR("Evgeniy Polyakov <zbr@ioremap.net>");
111262306a36Sopenharmony_ciMODULE_DESCRIPTION("DS2490 USB <-> W1 bus master driver (DS9490*)");
111362306a36Sopenharmony_ciMODULE_LICENSE("GPL");
1114