162306a36Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * linux/drivers/pcmcia/sa1100_neponset.c
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Neponset PCMCIA specific routines
662306a36Sopenharmony_ci */
762306a36Sopenharmony_ci#include <linux/module.h>
862306a36Sopenharmony_ci#include <linux/kernel.h>
962306a36Sopenharmony_ci#include <linux/device.h>
1062306a36Sopenharmony_ci#include <linux/errno.h>
1162306a36Sopenharmony_ci#include <linux/init.h>
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci#include <asm/mach-types.h>
1462306a36Sopenharmony_ci
1562306a36Sopenharmony_ci#include "sa1111_generic.h"
1662306a36Sopenharmony_ci#include "max1600.h"
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ci/*
1962306a36Sopenharmony_ci * Neponset uses the Maxim MAX1600, with the following connections:
2062306a36Sopenharmony_ci *
2162306a36Sopenharmony_ci *   MAX1600      Neponset
2262306a36Sopenharmony_ci *
2362306a36Sopenharmony_ci *    A0VCC        SA-1111 GPIO A<1>
2462306a36Sopenharmony_ci *    A1VCC        SA-1111 GPIO A<0>
2562306a36Sopenharmony_ci *    A0VPP        CPLD NCR A0VPP
2662306a36Sopenharmony_ci *    A1VPP        CPLD NCR A1VPP
2762306a36Sopenharmony_ci *    B0VCC        SA-1111 GPIO A<2>
2862306a36Sopenharmony_ci *    B1VCC        SA-1111 GPIO A<3>
2962306a36Sopenharmony_ci *    B0VPP        ground (slot B is CF)
3062306a36Sopenharmony_ci *    B1VPP        ground (slot B is CF)
3162306a36Sopenharmony_ci *
3262306a36Sopenharmony_ci *     VX          VCC (5V)
3362306a36Sopenharmony_ci *     VY          VCC3_3 (3.3V)
3462306a36Sopenharmony_ci *     12INA       12V
3562306a36Sopenharmony_ci *     12INB       ground (slot B is CF)
3662306a36Sopenharmony_ci *
3762306a36Sopenharmony_ci * The MAX1600 CODE pin is tied to ground, placing the device in
3862306a36Sopenharmony_ci * "Standard Intel code" mode. Refer to the Maxim data sheet for
3962306a36Sopenharmony_ci * the corresponding truth table.
4062306a36Sopenharmony_ci */
4162306a36Sopenharmony_cistatic int neponset_pcmcia_hw_init(struct soc_pcmcia_socket *skt)
4262306a36Sopenharmony_ci{
4362306a36Sopenharmony_ci	struct max1600 *m;
4462306a36Sopenharmony_ci	int ret;
4562306a36Sopenharmony_ci
4662306a36Sopenharmony_ci	ret = max1600_init(skt->socket.dev.parent, &m,
4762306a36Sopenharmony_ci			   skt->nr ? MAX1600_CHAN_B : MAX1600_CHAN_A,
4862306a36Sopenharmony_ci			   MAX1600_CODE_LOW);
4962306a36Sopenharmony_ci	if (ret == 0)
5062306a36Sopenharmony_ci		skt->driver_data = m;
5162306a36Sopenharmony_ci
5262306a36Sopenharmony_ci	return ret;
5362306a36Sopenharmony_ci}
5462306a36Sopenharmony_ci
5562306a36Sopenharmony_cistatic int
5662306a36Sopenharmony_cineponset_pcmcia_configure_socket(struct soc_pcmcia_socket *skt, const socket_state_t *state)
5762306a36Sopenharmony_ci{
5862306a36Sopenharmony_ci	struct max1600 *m = skt->driver_data;
5962306a36Sopenharmony_ci	int ret;
6062306a36Sopenharmony_ci
6162306a36Sopenharmony_ci	ret = sa1111_pcmcia_configure_socket(skt, state);
6262306a36Sopenharmony_ci	if (ret == 0)
6362306a36Sopenharmony_ci		ret = max1600_configure(m, state->Vcc, state->Vpp);
6462306a36Sopenharmony_ci
6562306a36Sopenharmony_ci	return ret;
6662306a36Sopenharmony_ci}
6762306a36Sopenharmony_ci
6862306a36Sopenharmony_cistatic struct pcmcia_low_level neponset_pcmcia_ops = {
6962306a36Sopenharmony_ci	.owner			= THIS_MODULE,
7062306a36Sopenharmony_ci	.hw_init		= neponset_pcmcia_hw_init,
7162306a36Sopenharmony_ci	.configure_socket	= neponset_pcmcia_configure_socket,
7262306a36Sopenharmony_ci	.first			= 0,
7362306a36Sopenharmony_ci	.nr			= 2,
7462306a36Sopenharmony_ci};
7562306a36Sopenharmony_ci
7662306a36Sopenharmony_ciint pcmcia_neponset_init(struct sa1111_dev *sadev)
7762306a36Sopenharmony_ci{
7862306a36Sopenharmony_ci	sa11xx_drv_pcmcia_ops(&neponset_pcmcia_ops);
7962306a36Sopenharmony_ci	return sa1111_pcmcia_add(sadev, &neponset_pcmcia_ops,
8062306a36Sopenharmony_ci				 sa11xx_drv_pcmcia_add_one);
8162306a36Sopenharmony_ci}
82